1. 程式人生 > >POJ1273 Drainage Ditches【dinic演算法】

POJ1273 Drainage Ditches【dinic演算法】

#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;
const int INF=1e9;
const int maxn=200+10; 
const int maxm=400+10;

struct Edge{
    Edge(){}
    Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
    int from,to,cap,flow;
};

struct Dinic{
	int n,m,s,t;                //結點數,邊數(包括反向弧),源點與匯點編號
    Edge edges[maxm];           //邊表 edges[e]和edges[e^1]互為反向弧
    int head[maxn],next[maxm];  //鄰接表表頭和next陣列
    bool vis[maxn];             //BFS使用,標記一個節點是否被遍歷過
    int d[maxn];                //從起點到i點的距離
    int cur[maxn];              //當前弧下標
    
    void Init(int n,int s,int t){
    	this->n=n,this->s=s,this->t=t;//this->n表示Dinic結構體裡的n,避免與函式引數衝突
		memset(head,-1,sizeof(head));
		m=0; 
	}
	
	void AddEdge(int from,int to,int cap){
		edges[m]=Edge(from,to,cap,0);
		next[m]=head[from];
		head[from]=m++;
		
		edges[m]=Edge(to,from,0,0);
		next[m]=head[to];
		head[to]=m++;
	}
	
	bool BFS(){
		memset(vis,0,sizeof(vis));
		queue<int> Q;
		Q.push(s);
		d[s]=0;
		vis[s]=true;
		while(!Q.empty()){
			int x=Q.front();Q.pop();
			for(int i=head[x]; i!=-1; i=next[i]){
				Edge& e=edges[i];
				if(!vis[e.to] && e.cap>e.flow){
					vis[e.to]=true;
					d[e.to]=d[x]+1;
					Q.push(e.to);
				}
			}
		}
		return vis[t];
	}
	
	int DFS(int x,int a){
		if(x==t||a==0) return a;
		int flow=0,f;
		for(int& i=cur[x];i!=-1;i=next[i]){
			Edge& e=edges[i];
			if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
				e.flow+=f;
				edges[i^1].flow-=f;
				flow+=f;
				a-=f;
				if(a==0) break;
			}
		}
		return flow;
	}
	
	int MaxFlow(){
		int flow=0;  
        while(BFS())  
        {  
            for(int i=1;i<=n;i++) cur[i]=head[i];  
            flow+=DFS(s,INF);  
        }  
        return flow;
	}
}DC;

int main()  
{  
	int n,m;
	while(scanf("%d%d",&m,&n)!=EOF){
		DC.Init(n,1,n);
		while(m--){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			DC.AddEdge(u,v,w);
		}
		printf("%d\n",DC.MaxFlow());
	}
    return 0;
}