通道: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 */