2400: Spoj 839 Optimal Marks

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 567  Solved: 202
[Submit][Status][Discuss]

Description

定义无向图中的一条边的值为:这条边连接的两个点的值的异或值。
定义一个无向图的值为:这个无向图所有边的值的和。
给你一个有n个结点m条边的无向图。其中的一些点的值是给定的,而其余的点的值由你决定(但要求均为非负数),使得这个无向图的值最小。在无向图的值最小的前提下,使得无向图中所有点的值的和最小。

Input

第一行,两个数n,m,表示图的点数和边数。
接下来n行,每行一个数,按编号给出每个点的值(若为负数则表示这个点的值由你决定,值的绝对值大小不超过10^9)。
接下来m行,每行二个数a,b,表示编号为a与b的两点间连一条边。(保证无重边与自环。)

Output

    第一行,一个数,表示无向图的值。
    第二行,一个数,表示无向图中所有点的值的和。

Sample Input

3 2
2
-1
0
1 2
2 3

Sample Output

2
2

HINT

数据约定
  n<=500,m<=2000

样例解释
    2结点的值定为0即可。

Source

Solution

刚开始看到可能束手无策,不过看见和xor有关,可以考虑分解成二进制的每一位,那么做法就有了

拆解成二进制去看每一位,建立一种最小割模型,S-->0;1-->T,很显然为inf,那么再连额外的边置成1;求最小割

第二问的话,找S集的点即可,那么直接搜一遍,累加进答案

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-')f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 20000
#define maxm 2000100
int n,m,val[maxn],Val[maxn];
struct EdgeNode{int next,to,cap;}edge[maxm<<];
int head[maxn],cnt=;
void add(int u,int v,int w) {cnt++;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt;edge[cnt].cap=w;}
void insert(int u,int v,int w) {add(u,v,w);add(v,u,);}
int dis[maxn],que[maxn<<],cur[maxn],S,T;
bool bfs()
{
for (int i=S; i<=T; i++) dis[i]=-;
que[]=S; dis[S]=; int he=,ta=;
while (he<ta)
{
int now=que[he++];
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==-)
dis[edge[i].to]=dis[now]+,que[ta++]=edge[i].to;
}
return dis[T]!=-;
}
int dfs(int loc,int low)
{
if (loc==T) return low;
int w,used=;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w;
used+=w; if (edge[i].cap) cur[loc]=i;
if (used==low) return low;
}
if (!used) dis[loc]=-;
return used;
}
#define inf 0x7fffffff
int dinic()
{
int tmp=;
while (bfs())
{
for (int i=S; i<=T; i++) cur[i]=head[i];
tmp+=dfs(S,inf);
}
return tmp;
}
int u[maxn],v[maxn];
void Build(int x)
{
cnt=; memset(head,,sizeof(head));
for (int i=; i<=n; i++)
if (val[i]>=)
if (val[i]&x) insert(i,T,inf);
else insert(S,i,inf);
for (int i=; i<=m; i++)
insert(u[i],v[i],),insert(v[i],u[i],);
}
bool visit[maxn];
void DFS(int x)
{
visit[x]=;
for (int i=head[x]; i; i=edge[i].next)
if (edge[i^].cap && !visit[edge[i].to])
DFS(edge[i].to);
}
long long ans,Ans;
int main()
{
// freopen("graph.in","r",stdin);
// freopen("graph.out","w",stdout);
n=read(); m=read(); S=,T=n+;
for (int i=; i<=n; i++) val[i]=read();
for (int i=; i<=m; i++) u[i]=read(),v[i]=read();
for (int i=; i<=; i++)
{
Build(<<i);
ans+=(long long)(<<i)*dinic();
memset(visit,,sizeof(visit)); DFS(T);
for (int j=; j<=n; j++) if (visit[j]) Val[j]+=(<<i);
}
for (int i=; i<=n; i++) Ans+=val[i]>?val[i]:Val[i];
printf("%lld\n%lld\n",ans,Ans);
return ;
}

【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS的更多相关文章

  1. [BZOJ 2127] happiness 【最小割】

    题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...

  2. BZOJ 2561 最小生成树 | 网络流 最小割

    链接 BZOJ 2561 题解 用Kruskal算法的思路来考虑,边(u, v, L)可能出现在最小生成树上,就是说对于所有边权小于L的边,u和v不能连通,即求最小割: 对于最大生成树的情况也一样.容 ...

  3. 【BZOJ2400】Spoj 839 Optimal Marks 最小割

    [BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...

  4. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  5. bzoj 3275 Number(最小割)

    [题意] 给定n个数,要求选出一些数满足 1.存在c,a*a+b*b=c*c 2.gcd(a,b)=1  使得和最大. [思路] 二分图的最大权独立集(可以这么叫么QAQ 先拆点,对于不满足条件的两个 ...

  6. bzoj 3144: [Hnoi2013]切糕 最小割

    3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 681  Solved: 375[Submit][Status] ...

  7. bzoj 3158 千钧一发(最小割)

    3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 767  Solved: 290[Submit][Status][Discuss] ...

  8. bzoj 3996: [TJOI2015]线性代数 [最小割]

    3996: [TJOI2015]线性代数 题意:给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 \(D=(A * B-C)* A^T\)最大.其中A^T为A的转置.输出D.每 ...

  9. ●BZOJ 1797 [Ahoi2009]Mincut 最小割

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1797 题解: 详细的讲解去看http://hzwer.com/3217.html首先跑一个最 ...

随机推荐

  1. Debian 8.2 下安装MySQL5.7.9 Generic Binaries

    安装过程参考了Installing MySQL on Unix/Linux Using Generic Binaries 首先检查是否安装libaio shell> apt-cache sear ...

  2. 【转】mysql触发器的实战(触发器执行失败,sql会回滚吗)

    1   引言Mysql的触发器和存储过程一样,都是嵌入到mysql的一段程序.触发器是mysql5新增的功能,目前线上凤巢系统.北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本,很多程 ...

  3. AngularJS中的过滤器

    欢迎大家指导与讨论 : ) 一.前言 AngularJS的过滤器能够将数据在被指令处理到显示在视图之前进行处理和转换.而且,过滤器不会修改作用域中的数据本身,即过滤器会保证数据的完整性.这样子能够允许 ...

  4. silverlight: http请求的GET及POST示例

    http请求的get/post并不是难事,只是silverlight中一切皆是异步,所以代码看起来就显得有些冗长了,下面这个HttpHelper是在总结 园友 的基础上,修改得来: namespace ...

  5. 打印机设置(PrintDialog)、页面设置(PageSetupDialog) 及 RDLC报表如何选择指定打印机

    如果一台电脑同时连接多个打印机,而且每个打印机使用的纸张大小各不相同(比如:票据打印钱用的小票专用张,办公打印机用的是A4标准纸),在处理打印类的需求时,如果不用代码干预,用户必须每次打印时,都必须在 ...

  6. opencv6.5-imgproc图像处理模块之轮廓

    接opencv6.4-imgproc图像处理模块之直方图与模板 这部分的<opencv_tutorial>上都是直接上代码,没有原理部分的解释的. 十一.轮廓 1.图像中找轮廓 /// 转 ...

  7. 封装好的socket,拿去用

    年终有空咯,分享一下自己封装的socket类库. 由于公司写的socket代码非常醉人,我不能忍,所以自己封装了一下方便大家使用,现在有空也分享给园友用用看,现在还存在一定的问题,等下我列出来,希望大 ...

  8. 出现“System.Data.SqlClient.SqlError: 尚未备份数据库的日志尾部”错误的解决方案

    Sql Server2008数据库在还原时出现如下错误信息:System.Data.SqlClient.SqlError: 尚未备份数据库<数据库名称>的日志尾部.如果该日志包含您不希望丢 ...

  9. 跨浏览器事件EventUtil

    <div style="width: 150px; height: 150px; padding: 25px; border:1px solid blue; " id=&qu ...

  10. Value cannot be null or empty. 参数名: contentPath

    代码:<img src="@Url.Content(item.ThumbPath)" width="160" height="250" ...