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;

}

 

你可能感兴趣的:(poj)