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. LeetCode 01 Two Sum swift

    class TwoSum { func sumTow(nums: [Int], target: Int)->[Int]{ ,]; ;x<nums.count;x++){ ;y<num ...

  2. 招聘高级.Net工程师

    找钢网创新开发部真诚地邀请程序猿\媛们加入,一起来吃大闸蟹午餐. 在创新开发部你可以见证一个产品从零开始到爆发到改变一个大宗商品的行业,在创新开发部你有机会接触到国际范,你还有机会接触到韩国的妹纸.欧 ...

  3. codevs 2651 孔子教学——同桌

    2651 孔子教学--同桌 题目描述 Description 孔子是我国古代著名的教育家.他有先见之明,可以判断学生出师以后给他带来的声望.声望共有三种"G""M&quo ...

  4. shell 使用

    echo -e "1\t2\t3" #-e echo -e "\e[1;31m This is red text \e[0m" #color echo -e & ...

  5. 【分布式协调器】Paxos的工程实现-cocklebur简介(二)

    Cocklebur集群的工作原理 在集群正常工作时,整个集群只会有一个Leader,其他都是Follower.Client可以注册到某个Follower,当然也可以注册到Leader,为了减轻Lead ...

  6. <实训|第十一天>学习一下linux中的进程,文件查找,文件压缩与IO重定向

    [root@localhost~]#序言 在今后的工作中,运维工程师每天的例行事务就是使用free -m,top,uptime,df -h...每天都要检查一下服务器,看看是否出现异常.那么今天我们就 ...

  7. ASP.NET XmlSerializer权限问题

    今天碰到一个奇怪问题.因为在2台服务器上做文件共享,使服务器A能访问服务器B的共享目录.在IIS上使用虚拟目录实现的话,需要给应用程序池指定一个统一的账号.在调试的时候能够使用,但是一部署到服务器上, ...

  8. ASP.NET 系列:单元测试之SmtpClient

    使用SmtpClient发送Email时,我们可以创建ISmtpClient接口和SmtpClientWrapper适配类,在单元测试中对ISmtpClient进行Mock或自定义FackeSmtpC ...

  9. Android开发环境部署

    引言   在windows系统中安装Android的开发环境,将分为五个步骤来完成: 第一步:安装JDK 第二步:配置Windows上JDK的变量环境 第三步: 下载安装Eclipse 第四步:下载安 ...

  10. [BZOJ 1997][HNOI2010]Planar(2-SAT)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1997 分析: 考虑每条边是在圈子里面还是圈子外面 所以就变成了2-SAT判定问题了= ...