最大流(推荐博客http://blog.csdn.net/mystery_guest/article/details/51910913)
不断增广
SAP模板
1 const int MAXN = 20010;//点数的最大值 2 const int MAXM = 880010;//边数的最大值 3 const int INF = 0x3f3f3f3f; 4 5 struct Node{ 6 int from, to, next; 7 int cap; 8 }edge[MAXM]; 9 int tol; 10 int head[MAXN]; 11 int dep[MAXN]; 12 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y 13 14 int n;//n是总的点的个数,包括源点和汇点 15 16 void init(){ 17 tol = 0; 18 memset(head, -1, sizeof(head)); 19 } 20 21 void addedge(int u, int v, int w){ 22 edge[tol].from = u; 23 edge[tol].to = v; 24 edge[tol].cap = w; 25 edge[tol].next = head[u]; 26 head[u] = tol++; 27 edge[tol].from = v; 28 edge[tol].to = u; 29 edge[tol].cap = 0; 30 edge[tol].next = head[v]; 31 head[v] = tol++; 32 } 33 34 void BFS(int start, int end){ 35 memset(dep, -1, sizeof(dep)); 36 memset(gap, 0, sizeof(gap)); 37 gap[0] = 1; 38 int que[MAXN]; 39 int front = 0, rear = 0; 40 dep[end] = 0; 41 que[rear++] = end; 42 while(front != rear){ 43 int u = que[front++]; 44 if(front == MAXN) front = 0; 45 for(int i = head[u]; i !=- 1; i = edge[i].next){ 46 int v = edge[i].to; 47 if(dep[v] != -1)continue; 48 que[rear++] = v; 49 if(rear == MAXN) rear = 0; 50 dep[v] = dep[u] + 1; 51 ++gap[dep[v]]; 52 } 53 } 54 } 55 56 int SAP(int start, int end){ 57 int res = 0; 58 BFS(start, end); 59 int cur[MAXN]; 60 int S[MAXN]; 61 int top = 0; 62 memcpy(cur, head, sizeof(head)); 63 int u = start; 64 int i; 65 while(dep[start] < n){ 66 if(u == end){ 67 int temp = INF; 68 int inser; 69 for(i = 0; i < top; i++) if(temp > edge[S[i]].cap){ 70 temp = edge[S[i]].cap; 71 inser = i; 72 } 73 for(i = 0; i < top; i++){ 74 edge[S[i]].cap -= temp; 75 edge[S[i]^1].cap += temp; 76 } 77 res += temp; 78 top = inser; 79 u = edge[S[top]].from; 80 } 81 if(u != end && gap[dep[u]-1] == 0)//出现断层,无增广路 82 break; 83 for(i = cur[u]; i != -1; i = edge[i].next) 84 if(edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1) 85 break; 86 if(i != -1){ 87 cur[u] = i; 88 S[top++] = i; 89 u = edge[i].to; 90 }else{ 91 int min = n; 92 for(i = head[u]; i != -1; i = edge[i].next){ 93 if(edge[i].cap == 0) continue; 94 if(min > dep[edge[i].to]){ 95 min = dep[edge[i].to]; 96 cur[u] = i; 97 } 98 } 99 --gap[dep[u]]; 100 dep[u] = min+1; 101 ++gap[dep[u]]; 102 if(u != start) u = edge[S[--top]].from; 103 } 104 } 105 return res; 106 }
只有不断学习才能进步!
原文:https://www.cnblogs.com/wenbao/p/7500305.html