【最小割】HDU 5294 Tricks Device

通道:http://acm.hdu.edu.cn/showproblem.php?pid=5294

题意:n个点,m条边的无向图,起点1,终点n,求1到n至少删除多少条边使得走不到,和最多删除多少条边使得依然有路((删不是最短路上边的图后))。

代码:裸--

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <iostream>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 const int MAX_N = 3007;
 10 const int MAX_M = 200007;
 11 const int INF = 0x3f3f3f3f;
 12 
 13 struct Node {
 14     int u, v, nxt;
 15     long long cap;
 16     Node () {}
 17     Node (int _u, int _v, int _n, long long _c) {
 18         u = _u;
 19         v = _v;
 20         nxt = _n;
 21         cap = _c;
 22     }
 23 };
 24 
 25 struct Isap {
 26     int n, s, t;
 27     int edgecnt;
 28     int head[MAX_N], d[MAX_N], gap[MAX_M << 2];
 29     Node G[MAX_M << 2];
 30     void init(int n, int s, int t) {
 31         this->n = n, this->s = s, this->t = t;
 32         edgecnt = 0;
 33         memset(head, -1, sizeof head);
 34     }
 35     void addedge(int u, int v, long long cap) {
 36         G[edgecnt] = Node(u, v, head[u], cap);
 37         head[u] = edgecnt++;
 38         G[edgecnt] = Node(v, u, head[v], 0);
 39         head[v] = edgecnt++;
 40     }
 41     long long dfs(int u, long long tot) {
 42         if (u == t) return tot;
 43         int minh = n - 1;
 44         long long leave = tot;
 45         for (int i = head[u]; ~i && leave; i = G[i].nxt) {
 46             int v = G[i].v;
 47             if (G[i].cap > 0) {
 48                 if (d[v] + 1 == d[u]) {
 49                     long long c = dfs(v, min(leave, G[i].cap));
 50                     G[i].cap -= c;
 51                     G[i ^ 1].cap += c;
 52                     leave -= c;
 53                     if (d[s] >= n) 
 54                         return tot - leave;
 55                 }
 56                 minh = min(minh, d[v]);
 57             }
 58         }
 59         if (leave == tot) {
 60             --gap[d[u]];
 61             if (gap[d[u]] == 0) d[s] = n;
 62             d[u] = minh + 1;
 63             ++gap[d[u]];
 64         }
 65         return tot - leave;
 66     }
 67     long long maxFlow() {
 68         long long ret = 0;
 69         memset(gap, 0, sizeof gap);
 70         memset(d, 0, sizeof d);
 71         gap[0] = n;
 72         while (d[s] < n) {
 73             ret += dfs(s, INF);
 74         }
 75         return ret;
 76     }
 77 };
 78 
 79 int n, m;
 80 int head[MAX_N], edgecnt1, edgecnt2, head2[MAX_N];
 81 int d1[MAX_N], d2[MAX_N], cnt[MAX_N];
 82 Node G[MAX_M << 2], G2[MAX_M << 2];
 83 bool vis[MAX_N];
 84 queue<int> que;
 85 
 86 void Clear() {
 87     edgecnt1 = 0;
 88     edgecnt2 = 0;
 89     memset(d1, 0, sizeof d1);
 90     memset(d2, 0, sizeof d2);
 91     memset(head, -1, sizeof head);
 92     memset(head2, -1, sizeof head2);
 93 }
 94 
 95 void add(int u, int v, int w) {
 96     G[edgecnt1] = Node(u, v, head[u], w);
 97     head[u] = edgecnt1++;
 98 }
 99 
100 void add2(int u, int v, int w) {
101     G2[edgecnt2] = Node(u, v, head2[u], w);
102     head2[u] = edgecnt2++;
103 }
104 
105 bool spfa(int u, int *d) {
106     fill(d, d + n + 3, INF);
107     memset(vis, false, sizeof vis);
108     memset(cnt, 0, sizeof cnt);
109     d[u] = 0; vis[u] = true;
110     while (!que.empty()) que.pop();
111     que.push(u);
112     while (!que.empty()) {
113         int u = que.front();vis[u] = false; que.pop();
114         for (int e = head[u]; e != -1; e = G[e].nxt) {  
115             int v = G[e].v;
116             if (d[v] > d[u] + G[e].cap) {
117                 d[v] = d[u] + G[e].cap;
118                 if (!vis[v]) {
119                     que.push(v); vis[v] = true;
120                 } 
121                 if (++cnt[v] > n) return false;
122             }
123         }
124     }
125 }
126 
127 int dp[MAX_N];
128 
129 int cal() {
130     fill(dp, dp + n + 3, INF);
131     memset(vis, false, sizeof vis);
132     memset(cnt, 0, sizeof cnt);
133     dp[1] = 0; vis[1] = true;
134     while (!que.empty()) que.pop();
135     que.push(1);
136     while (!que.empty()) {
137         int u = que.front();vis[u] = false; que.pop();
138         for (int e = head2[u]; e != -1; e = G2[e].nxt) {  
139             int v = G2[e].v;
140             if (dp[v] > dp[u] + 1) {
141                 dp[v] = dp[u] + 1;
142                 if (!vis[v]) {
143                     que.push(v); vis[v] = true;
144                 } 
145                 if (++cnt[v] > n) return false;
146             }
147         }
148     }
149     if (dp[n] == INF) return 0;
150     return dp[n];
151 }
152 
153 Isap now;
154 int main() {
155     while (2 == scanf("%d%d", &n, &m)) {
156         Clear();
157         now.init(n, 1, n);
158         for (int i = 0; i < m; ++i) {
159             int u, v, w;
160             scanf("%d%d%d", &u, &v, &w);
161             add(u, v, w);
162             add(v, u, w);
163             
164         }
165         spfa(1, d1), spfa(n, d2);
166         int way = 0;
167         for (int i = 0; i < edgecnt1; i++) {
168             int u = G[i].u, v = G[i].v;
169             if (d1[u] + d2[v] + G[i].cap != d1[n]) continue;
170             add2(u, v, G[i].cap);
171             add2(v, u, G[i].cap);
172             now.addedge(u, v, 1);
173             now.addedge(v, u, 1);
174             ++way;
175         }
176         int ans1 = now.maxFlow();
177         int ans2 = m - cal();
178         printf("%d %d\n", ans1, ans2);
179     }
180     return 0;
181 }
182 
183 /*
184 2 1
185 1 2 3
186 
187 8 10
188 1 2 2
189 2 3 2
190 2 4 1
191 3 5 3
192 4 5 4
193 5 8 1
194 1 6 2
195 6 7 5
196 7 8 1
197 1 8 2
198 
199 5 6
200 1 2 2
201 1 3 1
202 2 3 1
203 2 5 2
204 2 4 1
205 4 5 1
206 
207 9 11
208 1 2 1
209 2 3 1
210 2 4 1
211 1 5 1
212 5 6 1
213 5 7 1
214 3 8 1
215 4 8 1
216 6 8 1
217 7 8 1
218 8 9 1
219 
220 */
View Code

 

posted @ 2015-07-21 18:03  mithrilhan  阅读(141)  评论(0编辑  收藏  举报