bzoj 2400: Spoj 839 Optimal Marks
来源:互联网 发布:淘宝交易风险保障 15天 编辑:程序博客网 时间:2024/05/17 01:25
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
2
-1
0
1 2
2 3
Sample Output
2
2
2
HINT
数据约定
n<=500,m<=2000
样例解释
2结点的值定为0即可。
因为是xor,我们按位来做,跑最小割即可。
最讨厌写这种题了。。最近思路有点乱,详见代码
#include<cstdio>#include<string>#include<cstring>using namespace std;int head[100001];struct map{ int f; int s,t; int next;}a[400001];int b[5001];int edge;int p;int q[400001],d[400001];inline void add(int s,int t,int f){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t; a[edge].f=f;}inline bool bfs(){ int l=0,r=0; memset(q,0,sizeof(q)); r++; q[r]=0; memset(d,-1,sizeof(d)); d[0]=0; int i,k; while(l<r) { l++; int k=q[l]; for(i=head[k];i!=0;i=a[i].next) { if(a[i].f>0&&d[a[i].t]==-1) { d[a[i].t]=d[k]+1; r++; q[r]=a[i].t; } } } if(d[p]>=0) return true; return false;}inline int dfs(int k,int s){ if(k==p) return s; int t=s; int i; for(i=head[k];i!=0;i=a[i].next) { if(d[a[i].t]==d[k]+1&&a[i].f>0) { int xx=dfs(a[i].t,min(s,a[i].f)); a[i].f-=xx; if(i%2==0) a[i-1].f+=xx; else a[i+1].f+=xx; s-=xx; } } return t-s;}inline int maxflow(){ int s=0; while(bfs()) s+=dfs(0,2100000000); return s;}int n,m;int point[501];struct save{ int s,t;}edg[100001];inline void build(){ int i; memset(a,0,sizeof(a)); memset(head,0,sizeof(head)); edge=0; for(i=1;i<=m;i++) { edge++; add(edg[i].s,edg[i].t,1); edge++; add(edg[i].t,edg[i].s,1); } for(i=1;i<=n;i++) { if(point[i]>=0) { if(point[i]%2==1) { edge++; add(0,i,2100000000); edge++; add(i,0,0); } else { edge++; add(i,p,2100000000); edge++; add(p,i,0); } point[i]/=2; } }}int bt[501];int main(){ scanf("%d%d",&n,&m); int i,j; p=n+1; for(i=1;i<=n;i++) { scanf("%d",&point[i]); if(point[i]>=0) bt[i]=point[i]; } for(i=1;i<=m;i++) scanf("%d%d",&edg[i].s,&edg[i].t); long long ans=0,sum; long long pp=1; for(i=0;i<31;i++) { build(); sum=maxflow(); sum=sum*pp; ans+=sum; pp=pp*(long long)2; for(j=1;j<=n;j++) if(d[j]!=-1&&point[j]<0) bt[j]=bt[j]|(1<<i); } printf("%lld\n",ans); ans=0; for(i=1;i<=n;i++) ans+=bt[i]; printf("%lld\n",ans); return 0;}
0 0
- bzoj 2400: Spoj 839 Optimal Marks
- BZOJ 2400 Spoj 839 Optimal Marks
- bzoj 2400: Spoj 839 Optimal Marks
- 2400: Spoj 839 Optimal Marks
- 【 bzoj 2400 】Spoj 839 Optimal Marks - 最小割
- BZOJ 2400: Spoj 839 Optimal Marks|最小割
- bzoj 2400: Spoj 839 Optimal Marks (最小割)
- [最小割] BZOJ 2400 Spoj 839 Optimal Marks
- 【BZOJ 2400】Spoj 839 Optimal Marks 最小割
- BZOJ 2400: Spoj 839 Optimal Marks 网络流
- bzoj 2400: Spoj 839 Optimal Marks(最小割)
- spoj 839(Optimal Marks)
- spoj 839 Optimal Marks
- SPOJ 839 Optimal Marks
- SPOJ 839 Optimal Marks
- 2400: Spoj 839 Optimal Marks 最小割
- BZOJ2400 Spoj 839 Optimal Marks
- BZOJ2400: Spoj 839 Optimal Marks
- 二叉树后续遍历的非递归循环C# 实现
- MFC中 调用控制台
- spark1.1.0学习路线
- 反调试技术常用API,用来对付检测od和自动退出程序
- 程序员最值得关注的10个C开源项目
- bzoj 2400: Spoj 839 Optimal Marks
- sudo 运行 x11程序
- 第9周项目3(1)-星号图
- 自定义ListView中的分割线
- BroadcastReceiver.PendingResult类
- 二维数组中的查找
- 利用数据库虚拟化来搭建开发、测试环境
- SVN 多分支的情况如何进行合并
- UVA - 10706 Number Sequence