首页 > 代码库 > poj1087最小割
poj1087最小割
最大流最小割定理:移除最小边集使网络流中断的集值等于这个网络的最大流。
建图: 第一个cpu 流向第i的 模块的流量为ai , 第i个模块流向 第二个cpu的流量为 bi 。模块之间连边 a->b= w b->a=w。
#include <cstdio>#include <cstring>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>using namespace std;int s;int en;int n;int m;struct edge{ int to;int val;int next;int op;}e[1111111];const int INF=0xfffffff;int Min(int a,int b){ return a>b?b:a;}int len;int head[111111];int level[111111];void add(int from,int to,int val){ e[len].val=val;e[len].to=to;e[len].next=head[from];e[len].op=len+1; head[from]=len++; e[len].val=0;e[len].to=from;e[len].next=head[to];e[len].op=len-1; head[to]=len++;}bool bfs(){ for(int i=0;i<n+2;i++) level[i]=0; level[s]=1; queue<int > q; q.push(s); while(!q.empty()){ int cur=q.front(); q.pop(); for(int i=head[cur];i!=-1;i=e[i].next){ if(!e[i].val) continue; int cc=e[i].to; if(!level[cc]){ level[cc]=level[cur]+1; q.push(cc); } } } return level[en];}int dfs(int x,int val){ int tem=val; if(x==en) return val; for(int i=head[x];i!=-1&&tem;i=e[i].next){ if(!e[i].val) continue; int cc=e[i].to; // cout<<cc<<" "<<x<<endl;system("pause"); if(level[cc]==level[x]+1){ // cout<<x<<" "<<cc<<" "<<e[i].val<<endl; int t=dfs(cc,Min(tem,e[i].val)); e[i].val-=t; e[e[i].op].val+=t; tem-=t; } } return val-tem;}int dinic(){ int ans=0;int t; while(bfs()){ while(t=dfs(s,INF)) ans+=t; } return ans;}int main(){ while(scanf("%d%d",&n,&m)!=EOF){ len=0; memset(head,-1,sizeof(head)); s=0;en=n+1; for(int i=1;i<=n;i++){ int a;int b; scanf("%d%d",&a,&b); add(s,i,a);add(i,en,b); } for(int i=0;i<m;i++){ int a;int b;int c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } cout<<dinic()<<endl; } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。