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. uwp项目总结

  2. 047医疗项目-模块四:采购单模块—采购单审核提交(Dao,Service,Action三层)

    我们之前把采购单都审核了,这篇文章说的就是审核之后提交. 其实就是改变(update)采购单的审核状态. 需求: 用户要先查看采购单的内容. 查看采购单页面:页面布局同采购单修改页面. 选择审核结果. ...

  3. node基础03:使用函数

    1.使用函数 //server.js var http = require("http"); var output = require("./output"); ...

  4. ThreadLocal原理及其实际应用

    前言 java猿在面试中,经常会被问到1个问题: java实现同步有哪几种方式? 大家一般都会回答使用synchronized, 那么还有其他方式吗? 答案是肯定的, 另外一种方式也就是本文要说的Th ...

  5. .html 、.htm 、 .shtml 以及 .shtm 四种扩展名的文件区别

    新增了一个分类,叫做 Personals,中文我把它解释成 "个人恶趣味",这里将记载一些对工作无关紧要,但是个人又一时有兴趣了解的东西. 今天要讲的是如题的 4 种扩展文件的区别 ...

  6. SQL基础之select

    1.认识select select的主要语法如下,这个很重要因为只有记住了整体的结构才能应对任何情况.从中可以看到select的强大主要就是建立在where.group by.having.order ...

  7. 最佳实践 —— 详细谈谈如何减小APK体积

    转载请注明出处: http://www.cnblogs.com/soaringEveryday/p/5254520.html 随着Android移动开发的需求越来越复杂,我们不可避免的遇到发布出去的a ...

  8. [转]java 输出流转输入流

    ByteArrayOutputStream.toByteArray ByteArrayInputStream StringWriter.toString StringReader 字符流和二进制流是j ...

  9. RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重的错误日 ...

  10. zabbix解决中文乱码问题(没有测试成功)

    zabbix解决中文乱码问题 1.在windows系统中找一个自己喜欢的字体,这里我们用:msyh.ttf 2.将字体上传至/var/www/html/zabbix/fonts目录下 [root@za ...