POJ1273 Drainage Ditches【dinic演算法】
阿新 • • 發佈:2018-12-19
#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; }