最小割应用~
View Code
1 #include <cstdio>
2 #include <cstring>
3
4 constint INF = (1<<30);
5
6 class Network
7 {
8 private:
9 conststaticint MAXV =512; // 顶点数
10 conststaticint 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 void 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 void Network::Augment(int& sum)
105 {
106 int minl = INF;
107 for (int u = t;u != s;u = pred[u])
108 minl = minl < path[u]->f ? minl : path[u]->f;
109 sum += minl;
110 for (int u = t;u != s;u = pred[u])
111 {
112 path[u]->f -= minl;
113 path[u]->rev->f += minl;
114 }
115
116 return;
117 }
118
119 int Network::maxFlow()
120 {
121 bool update;
122 int u = s;
123 int ret =0;
124
125 InitDist();
126 for (int i =0;i < n;i++)
127 cur[i] = head[i];
128
129 while (dist[s] < n)
130 {
131 update =false;
132 for (List * p = cur[u];p;p = p->next)
133 if (dist[p->v] +1== dist[u] && p->f >0)
134 {
135 update =true;
136 pred[p->v] = u;
137 path[p->v] = p;
138 cur[u] = p;
139 u = p->v; // 前进步
140 if (u == t)
141 {
142 Augment(ret);
143 u = s;
144 }
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
175 while(scanf("%d %d",&nd,&nw) != EOF)
176 {
177 net.Init(nd +2,0,nd +1);
178
179 for(int i =1;i <= nd;i++)
180 {
181 scanf("%d",&val);
182 net.addEdge(0,i,val);
183 }
184
185 for(int i =1;i <= nd;i++)
186 {
187 scanf("%d",&val);
188 net.addEdge(i,nd +1,val);
189 }
190
191 for(int i =0;i < nw;i++)
192 {
193 scanf("%d %d %d",&u,&v,&val);
194 net.addEdge(u,v,val);
195 net.addEdge(v,u,val);
196 }
197
198 printf("%d\n",net.maxFlow());
199 }
200 return0;
201 }
2 #include <cstring>
3
4 constint INF = (1<<30);
5
6 class Network
7 {
8 private:
9 conststaticint MAXV =512; // 顶点数
10 conststaticint 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 void 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 void Network::Augment(int& sum)
105 {
106 int minl = INF;
107 for (int u = t;u != s;u = pred[u])
108 minl = minl < path[u]->f ? minl : path[u]->f;
109 sum += minl;
110 for (int u = t;u != s;u = pred[u])
111 {
112 path[u]->f -= minl;
113 path[u]->rev->f += minl;
114 }
115
116 return;
117 }
118
119 int Network::maxFlow()
120 {
121 bool update;
122 int u = s;
123 int ret =0;
124
125 InitDist();
126 for (int i =0;i < n;i++)
127 cur[i] = head[i];
128
129 while (dist[s] < n)
130 {
131 update =false;
132 for (List * p = cur[u];p;p = p->next)
133 if (dist[p->v] +1== dist[u] && p->f >0)
134 {
135 update =true;
136 pred[p->v] = u;
137 path[p->v] = p;
138 cur[u] = p;
139 u = p->v; // 前进步
140 if (u == t)
141 {
142 Augment(ret);
143 u = s;
144 }
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
175 while(scanf("%d %d",&nd,&nw) != EOF)
176 {
177 net.Init(nd +2,0,nd +1);
178
179 for(int i =1;i <= nd;i++)
180 {
181 scanf("%d",&val);
182 net.addEdge(0,i,val);
183 }
184
185 for(int i =1;i <= nd;i++)
186 {
187 scanf("%d",&val);
188 net.addEdge(i,nd +1,val);
189 }
190
191 for(int i =0;i < nw;i++)
192 {
193 scanf("%d %d %d",&u,&v,&val);
194 net.addEdge(u,v,val);
195 net.addEdge(v,u,val);
196 }
197
198 printf("%d\n",net.maxFlow());
199 }
200 return0;
201 }