题目大意:
无向图,求最大流。
算法讨论:
Dinic可过。终于我的常数还是太大。以后要注意下了。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 using namespace std; 8 typedef long long ll; 9 10 struct MF{ 11 static const int N = 5000 + 5; 12 static const int M = 60000 + 5; 13 static const ll oo = 10000000000000LL; 14 15 int n, m, s, t, tot, tim; 16 int first[N], next[M]; 17 int u[M], v[M], cur[N], vi[N]; 18 ll cap[M], flow[M], dis[N]; 19 int que[N + N]; 20 21 void Clear(){ 22 tot = 0;tim = 0; 23 for(int i = 1; i <= n; ++ i) first[i] = -1; 24 } 25 void Add(int from, int to, ll cp, ll flw){ 26 u[tot] = from; v[tot] = to; cap[tot] = cp; flow[tot] = flw; 27 next[tot] = first[u[tot]]; 28 first[u[tot]] = tot; 29 ++ tot; 30 } 31 bool bfs(){ 32 ++ tim; 33 dis[s] = 0;vi[s] = tim; 34 35 int head, tail; 36 head = tail = 1; 37 que[head] = s; 38 while(head <= tail){ 39 for(int i = first[que[head]]; i != -1; i = next[i]){ 40 if(vi[v[i]] != tim && cap[i] > flow[i]){ 41 vi[v[i]] = tim; 42 dis[v[i]] = dis[que[head]] + 1; 43 que[++ tail] = v[i]; 44 } 45 } 46 ++ head; 47 } 48 return vi[t] == tim; 49 } 50 ll dfs(int x, ll a){ 51 if(x == t || a == 0) return a; 52 ll flw = 0, f; 53 int &i = cur[x]; 54 for(i = first[x]; i != -1; i = next[i]){ 55 if(dis[x] + 1 == dis[v[i]] && (f = dfs(v[i], min(a, cap[i]-flow[i]))) > 0){ 56 flow[i] += f; flow[i^1] -= f; 57 a -= f; flw += f; 58 if(a == 0) break; 59 } 60 } 61 return flw; 62 } 63 ll MaxFlow(int s, int t){ 64 this->s = s;this->t = t; 65 ll flw = 0; 66 while(bfs()){ 67 for(int i = 1; i <= n; ++ i) cur[i] = 0; 68 flw += dfs(s, oo); 69 } 70 return flw; 71 } 72 }Net; 73 int n, m; 74 75 int main(){ 76 int x, y; 77 ll z; 78 scanf("%d%d", &n, &m); 79 Net.n = n; 80 Net.Clear(); 81 for(int i = 1; i <= m; ++ i){ 82 scanf("%d%d%lld", &x, &y, &z); 83 Net.Add(x, y, z, 0); 84 Net.Add(y, x, z, 0); 85 } 86 printf("%lld\n", Net.MaxFlow(1,Net.n)); 87 return 0; 88 }