题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549
题意:
给你一个有向图,问你1到n的最大流。
dinic模版 (n*n*m)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 1000; //点个数 6 const int M = 10000; //边个数 7 const int inf = 0x3f3f3f3f; 8 struct Edge { 9 int to, next, cap, flow; 10 }edge[M]; 11 int tot, head[N]; 12 void init() { 13 tot = 0; 14 memset(head, -1, sizeof(head)); 15 } 16 inline void add(int u, int v, int w, int rw = 0) { 17 edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; 18 edge[tot].next = head[u]; head[u] = tot++; 19 edge[tot].to = u; edge[tot].cap = rw; edge[tot].flow = 0; 20 edge[tot].next = head[v]; head[v] = tot++; 21 } 22 int Q[N]; 23 int dep[N], cur[N], sta[N]; 24 bool bfs(int s, int t, int n) { 25 int front = 0, tail = 0; 26 memset(dep, -1, sizeof(dep[0])*(n + 1)); 27 dep[s] = 0; 28 Q[tail++] = s; 29 while(front < tail) { 30 int u = Q[front++]; 31 for(int i = head[u]; ~i; i = edge[i].next) { 32 int v = edge[i].to; 33 if(edge[i].cap > edge[i].flow && dep[v] == -1) { 34 dep[v] = dep[u] + 1; 35 if(v == t) 36 return true; 37 Q[tail++] = v; 38 } 39 } 40 } 41 return false; 42 } 43 44 int dinic(int s, int t, int n) { 45 int maxflow = 0; 46 while(bfs(s, t, n)) { 47 for(int i = 0; i < n; ++i) 48 cur[i] = head[i]; 49 int u = s, tail = 0; 50 while(cur[s] != -1) { 51 if(u == t) { 52 int tp = inf; 53 for(int i = tail - 1; i >= 0; --i) { 54 tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow); 55 } 56 maxflow += tp; 57 for(int i = tail - 1; i >= 0; --i) { 58 edge[sta[i]].flow += tp; 59 edge[sta[i] ^ 1].flow -= tp; 60 if(edge[sta[i]].cap - edge[sta[i]].flow == 0) 61 tail = i; 62 } 63 u = edge[sta[tail] ^ 1].to; 64 } else if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) { 65 sta[tail++] = cur[u]; 66 u = edge[cur[u]].to; 67 } else { 68 while(u != s && cur[u] == -1) { 69 u = edge[sta[--tail] ^ 1].to; 70 } 71 cur[u] = edge[cur[u]].next; 72 } 73 } 74 } 75 return maxflow; 76 } 77 78 int main() 79 { 80 int t, n, m, u, v, c; 81 scanf("%d", &t); 82 for(int ca = 1; ca <= t; ++ca) { 83 scanf("%d %d", &n, &m); 84 init(); 85 for(int i = 1; i <= m; ++i) { 86 scanf("%d %d %d", &u, &v, &c); 87 add(u, v, c); 88 } 89 printf("Case %d: %d\n", ca, dinic(1, n, n)); 90 } 91 return 0; 92 }
貌似一般比dinic更优一点
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 1e3 + 5; 6 const int M = 1e4 + 5; 7 const int inf = 0x3f3f3f3f; 8 struct Edge { 9 int to, next, cap, flow; 10 }edge[M]; 11 int tot, head[N], gap[N], dep[N], cur[N]; 12 void init() { 13 tot = 0; 14 memset(head, -1, sizeof(head)); 15 } 16 void addedge(int u, int v, int w, int rw = 0) { 17 edge[tot].next = head[u]; edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; head[u] = tot++; 18 edge[tot].next = head[v]; edge[tot].to = u; edge[tot].cap = rw; edge[tot].flow = 0; head[v] = tot++; 19 } 20 int Q[N]; 21 void bfs(int start, int end) { 22 memset(dep, -1, sizeof(dep)); 23 memset(gap, 0, sizeof(gap)); 24 gap[0] = 1; 25 int front = 0, rear = 0; 26 dep[end] = 0; 27 Q[rear++] = end; 28 while(front != rear) { 29 int u = Q[front++]; 30 for(int i = head[u]; ~i; i = edge[i].next) { 31 int v = edge[i].to; 32 if(dep[v] != -1) 33 continue; 34 Q[rear++] = v; 35 dep[v] = dep[u] + 1; 36 gap[dep[v]]++; 37 } 38 } 39 } 40 int S[N]; 41 int sap(int start, int end, int N) { 42 bfs(start, end); 43 memcpy(cur, head, sizeof(head)); 44 int top = 0; 45 int u = start; 46 int ans = 0; 47 while(dep[start] < N) { 48 if(u == end) { 49 int Min = inf; 50 int inser; 51 for(int i = 0; i < top; ++i) { 52 if(Min > edge[S[i]].cap - edge[S[i]].flow) { 53 Min = edge[S[i]].cap - edge[S[i]].flow; 54 inser = i; 55 } 56 } 57 for(int i = 0; i < top; ++i) { 58 edge[S[i]].flow += Min; 59 edge[S[i] ^ 1].flow -= Min; 60 } 61 ans += Min; 62 top = inser; 63 u = edge[S[top] ^ 1].to; 64 continue; 65 } 66 bool flag = false; 67 int v; 68 for(int i = cur[u]; ~i; i = edge[i].next) { 69 v = edge[i].to; 70 if(edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u]) { 71 flag = true; 72 cur[u] = i; 73 break; 74 } 75 } 76 if(flag) { 77 S[top++] = cur[u]; 78 u = v; 79 continue; 80 } 81 int Min = N; 82 for(int i = head[u]; ~i; i = edge[i].next) { 83 if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { 84 Min = dep[edge[i].to]; 85 cur[u] = i; 86 } 87 } 88 gap[dep[u]]--; 89 if(!gap[dep[u]]) 90 return ans; 91 dep[u] = Min + 1; 92 gap[dep[u]]++; 93 if(u != start) 94 u = edge[S[--top] ^ 1].to; 95 } 96 return ans; 97 } 98 99 int main() 100 { 101 int t, n, m, u, v, c; 102 scanf("%d", &t); 103 for(int ca = 1; ca <= t; ++ca) { 104 scanf("%d %d", &n, &m); 105 init(); 106 for(int i = 0; i < m; ++i) { 107 scanf("%d %d %d", &u, &v, &c); 108 addedge(u, v, c); 109 } 110 printf("Case %d: %d\n", ca, sap(1, n, n)); 111 } 112 return 0; 113 }