首页 > 代码库 > 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;}