Drainage Ditches(网络流(EK算法))
计算最大流,EK算法模板题。
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 using namespace std; 5 const int maxn=520; 6 const int maxm=100010; 7 const int INF=1<<28; 8 int n,m,s,t,cnt,max_flow; 9 int head[maxn],pre[maxn],a[maxn]; 10 11 struct node 12 { 13 int u; 14 int v; 15 int cap; 16 int next; 17 } edge[maxm]; 18 void init() 19 { 20 memset(head,-1,sizeof(head)); 21 cnt = 2; 22 } 23 void add(int u,int v,int cap)//用邻接表存储 24 { 25 edge[cnt].u = u; 26 edge[cnt].v = v; 27 edge[cnt].cap = cap; 28 edge[cnt].next = head[u]; 29 head[u] = cnt++; 30 } 31 void EK(int s) 32 { 33 queue<int>q; 34 max_flow = 0; 35 for (;;) 36 { 37 memset(a,0,sizeof(a)); 38 q.push(s); 39 a[s] = INF;//源点容量为无穷 40 while(!q.empty()) 41 { 42 int u = q.front(); 43 q.pop(); 44 for (int i = head[u]; i!=-1; i=edge[i].next) 45 { 46 int v = edge[i].v; 47 if (!a[v] && edge[i].cap > 0) 48 { 49 q.push(v); 50 pre[v] = i;// 记录V的前驱的下标 51 a[v] = std::min(a[u],edge[i].cap);//更新每个节点的flow 52 } 53 } 54 } 55 if(a[t]==0) 56 break; 57 int i; 58 for (int u = t; u!=s; u = edge[i].u)//修改增光路 59 { 60 i = pre[u]; 61 edge[i].cap -= a[t];//正向的边容量减去残余量 62 edge[i^1].cap += a[t];//反向的边容量(初始为0)加上残余量 63 } 64 max_flow += a[t]; 65 } 66 } 67 int main() 68 { 69 while(~scanf("%d%d",&m,&n)) 70 { 71 init(); 72 while(m--) 73 { 74 int u,v,w; 75 scanf("%d%d%d",&u,&v,&w); 76 add(u,v,w); 77 add(v,u,0);//加反向边 78 79 } 80 s = 1; 81 t = n; 82 EK(s); 83 printf("%d\n",max_flow); 84 } 85 return 0; 86 }