bzoj 2400: Spoj 839 Optimal Marks
来源:互联网 发布:淘宝 iphone att群 编辑:程序博客网 时间:2024/06/05 17:25
2400: Spoj 839 Optimal Marks
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 668 Solved: 248
[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
2
-1
0
1 2
2 3
Sample Output
2
2
2
HINT
数据约定
n<=500,m<=2000
样例解释
2结点的值定为0即可。
将异或操作分解到每一位,则变为0和1两种选择,且不同要付出1的代价,那么每一位做一个最小割
代码:
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<climits>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#define N 10001#define M 2000020#define inf 1<<26using namespace std;typedef long long ll;inline ll read(){ ll x=0,f=1;char ch; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}ll n,m,s,t,c[N],uu[N],vv[N];ll head[N],pos=-1,cur[N];struct edge{ll to,next,c;}e[M];void add(ll a,ll b,ll c){pos++;e[pos].to=b,e[pos].c=c,e[pos].next=head[a],head[a]=pos;}void insert(ll a,ll b,ll c){add(a,b,c);add(b,a,0);}queue<ll>Q;bool vis[N];ll d[N];bool bfs(){ for(ll i=s;i<=t;i++)vis[i]=0,d[i]=-1; Q.push(s);vis[s]=1,d[s]=0; while(!Q.empty()) {ll u=Q.front();Q.pop();for(ll i=head[u];i!=-1;i=e[i].next){ ll v=e[i].to; if(vis[v]||e[i].c<=0)continue; d[v]=d[u]+1;vis[v]=1;Q.push(v);} }return vis[t];}ll dfs(ll u,ll a){ if(u==t||!a)return a; ll flow=0,f; for(ll &i=cur[u];i!=-1;i=e[i].next) {ll v=e[i].to;if(d[v]==d[u]+1&&(f=dfs(v,min(e[i].c,a)))>0){ flow+=f,a-=f; e[i].c-=f,e[i^1].c+=f; if(!a)break;} }return flow;}ll dinic(){ ll ret=0; while(bfs()) {for(ll i=s;i<=t;i++)cur[i]=head[i];ret+=dfs(s,inf); }return ret;}void init(){pos=-1;memset(head,-1,sizeof(head));}bool build(){ init();bool f=0; for(ll i=1;i<=n;i++) {if(c[i]<0)continue;ll k=c[i]&1;f|=c[i]?1:0;c[i]>>=1;if(k)insert(s,i,inf);else insert(i,t,inf); } for(ll i=1;i<=m;i++) {add(uu[i],vv[i],1);add(vv[i],uu[i],1); }return f;}void dfs(ll u){vis[u]=1;for(ll i=head[u];i!=-1;i=e[i].next){ll v=e[i].to;if(vis[v]||e[i].c<=0)continue;dfs(v);}}ll val[N],ans,v[N];ll solve(){ ll ret=0,tme=1; while(1) {if(!build())break;ret+=tme*dinic();for(ll i=1;i<=n;i++)vis[i]=0;dfs(s);for(ll i=1;i<=n;i++)if(vis[i])val[i]+=tme;tme<<=1; }return ret;}int main(){ n=read(),m=read();s=0,t=n+1; for(ll i=1;i<=n;i++)v[i]=c[i]=read(); for(ll i=1;i<=m;i++)uu[i]=read(),vv[i]=read(); printf("%lld\n",solve()); for(ll i=1;i<=n;i++) ans+=v[i]>=0?v[i]:val[i]; printf("%lld\n",ans);}
1 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
- 设计模式-适配器模式
- 图的深度遍历——java实现
- 简单几步实现网络音乐播放器(Qt版百度FM)
- MongoDB的使用及集群搭建
- 数据结构——链队列——2016_12_27
- bzoj 2400: Spoj 839 Optimal Marks
- TCP与应用层协议
- Leetcode刷题记—— Search a 2D Matrix(在二维数组里查找)
- Linux内核模块
- 第3章-1 创建ndarray 学习笔记
- 2016这一年读过的那些书
- 【oracle游标二】游标循环方式
- Waiting for table metadata lock
- 性能优化一点总结