1. 程式人生 > >USACO4.2.1 網絡流最大流算法

USACO4.2.1 網絡流最大流算法

name 網絡流最大流 算法 ask freopen class 最大 names ++

/*
ID:hk945801
TASK:ditch
LANG:C++
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int inf=10000001;
struct node{
	int c,f;
}a[201][201];
int p[201*201],d[201*201],pre[201];
int main(){
	int i,j,k,m,n;
	int x;
	freopen("ditch.in","r",stdin);
	freopen("ditch.out","w",stdout);
	cin>>m>>n;  
    for(i=1;i<=m;i++){
	    int x,y,z;  
        scanf("%d%d%d",&x,&y,&z);                    
        a[x][y].c+=z;  
    } 
    int pd=1;
    while(pd){
	    pd=0;
	    int fi=0,l=1;
	    d[1]=1;
	    for(i=1;i<=n;i++)p[i]=0;  
        p[1]=1;  
        while(fi<l){  
            fi++;
        x=d[fi];
            for(i=2;i<=n;i++)
                if(!p[i] && (a[x][i].c>a[x][i].f || a[i][x].f>0)){  
                    d[++l]=i;
                    p[i]=1;
                    pre[i]=x;
                    if(i==n){pd=1;break;}  
                }         
            if(pd==1)break;  
        }  
        if(pd==0)break;  
        int min=inf;  
        x=n;  
        while(x!=1){  
            if(a[pre[x]][x].c>a[pre[x]][x].f&& a[pre[x]][x].c-a[pre[x]][x].f<min)  
                min=a[pre[x]][x].c-a[pre[x]][x].f;             
            else if(a[x][pre[x]].f>0 && a[x][pre[x]].f<min)  
                min=a[x][pre[x]].f;  
            x=pre[x];  
        }  
        x=n;  
        while(x!=1){  
            if(a[pre[x]][x].c>a[pre[x]][x].f)  
                a[pre[x]][x].f+=min;              
            else if(a[x][pre[x]].f>0)  
                a[x][pre[x]].f-=min;  
            x=pre[x];
        }
	}
	int ans=0;  
    for(i=2;i<=n;i++)  
        ans+=a[1][i].f;  
    cout<<ans<<endl;
	return 0;
}

USACO4.2.1 網絡流最大流算法