赤裸裸最大流~

View Code
1 #include <cstdio>
2 #include <cstring>
3
4  const int INF = (1 << 30);
5
6  class Network
7 {
8 private:
9 const static int MAXV = 512; // 顶点数
10 const static int MAXE = 512000; // 边数 * 2
11
12 struct List
13 {
14 int v;
15 int f;
16 List * rev;
17 List * next;
18 };
19
20 List pool[MAXE];
21 List * path[MAXV];
22 List * head[MAXV];
23 List * cur[MAXV];
24 List * pp;
25
26 int n;
27 int s;
28 int t;
29 int dist[MAXV];
30 int num[MAXV];
31 int pred[MAXV];
32
33 inline List * create(int v,int f,List * next)
34 {
35 pp->v = v;
36 pp->f = f;
37 pp->next = next;
38 return pp++;
39 }
40
41 void InitDist();
42 int Augment(int &);
43 public:
44 void Init(int nv,int ss,int tt);
45 void addEdge(int u,int v,int f);
46 int maxFlow();
47 };
48
49 void Network::Init(int nv,int ss,int tt)
50 {
51 n = nv;
52 s = ss;
53 t = tt;
54
55 pp = pool;
56 memset(head,0,n * sizeof(head[0]));
57 memset(cur,0,n * sizeof(cur[0]));
58 memset(num,0,n * sizeof(int));
59
60 pred[s] = -1;
61
62 for (int i = 0;i < n;i++)
63 dist[i] = n;
64
65 return;
66 }
67
68 void Network::addEdge(int u,int v,int f)
69 {
70 head[u] = create(v,f,head[u]);
71 head[v] = create(u,0,head[v]);
72
73 head[u]->rev = head[v];
74 head[v]->rev = head[u];
75
76 return;
77 }
78
79 void Network::InitDist()
80 {
81 int queue[MAXV];
82 int qh = -1;
83 int qe = 0;
84
85 dist[t] = 0;
86 queue[0] = t;
87
88 while (qh != qe)
89 {
90 qh++;
91 int u = queue[qh];
92 for (List * p = head[u];p;p = p->next)
93 if (p->f == 0 && dist[p->v] == n)
94 {
95 dist[p->v] = dist[u] + 1;
96 num[dist[p->v]]++;
97 queue[++qe] = p->v;
98 }
99 }
100
101 return;
102 }
103
104 int Network::Augment(int & sum)
105 {
106 int last = s;
107 int minl = INF;
108 for (int u = t;u != s;u = pred[u])
109 minl = minl < path[u]->f ? minl : path[u]->f;
110 sum += minl;
111 for (int u = t;u != s;u = pred[u])
112 {
113 path[u]->f -= minl;
114 path[u]->rev->f += minl;
115 if(path[u]->f == 0)
116 last = pred[u];
117 }
118
119 return last;
120 }
121
122 int Network::maxFlow()
123 {
124 bool update;
125 int u = s;
126 int ret = 0;
127
128 InitDist();
129 for (int i = 0;i < n;i++)
130 cur[i] = head[i];
131
132 while (dist[s] < n)
133 {
134 update = false;
135 for (List * p = cur[u];p;p = p->next)
136 if (dist[p->v] + 1 == dist[u] && p->f > 0)
137 {
138 update = true;
139 pred[p->v] = u;
140 path[p->v] = p;
141 cur[u] = p;
142 u = p->v; // 前进步
143 if (u == t)
144 u = Augment(ret);
145 break;
146 }
147 if (!update)
148 {
149 if ( --num[dist[u]] == 0) // 间隙优化
150 break;
151 cur[u] = head[u];
152 dist[u] = n;
153 for (List * p = head[u];p;p = p->next) // 重标号
154 if (p->f > 0 && dist[u] > dist[p->v] + 1)
155 dist[u] = dist[p->v] + 1;
156 if (dist[u] < n)
157 num[dist[u]]++;
158 if (u != s) // 回退步
159 u = pred[u];
160 }
161 }
162 return ret;
163 }
164
165 Network net;
166
167 int main()
168 {
169 int nd;
170 int nw;
171 int u;
172 int v;
173 int val;
174 int cas;
175
176 scanf("%d",&cas);
177 for(int cc = 0;cc < cas;cc++)
178 {
179 scanf("%d %d",&nd,&nw);
180 net.Init(nd,0,nd - 1);
181 for(int i = 0;i < nw;i++)
182 {
183 scanf("%d %d %d",&u,&v,&val);
184 net.addEdge(u-1,v-1,val);
185 }
186 printf("Case %d: %d\n",cc+1,net.maxFlow());
187 }
188 return 0;
189 }