Similar to http://blog.csdn.net/wyfcyx_forever/article/details/39345281. Only the minimum number of damaged nodes is obtained.
SOL:
Minimum split point cut.
S-> 1 c = inf
Point X x'-> T c = inf
For each vertex x, it is 1 or the mentioned vertex x-> X 'C = inf
For each vertex x, It is not 1 and is not the mentioned vertex x-> X 'C = 1.
For each side of the source image X-> Y x'-> y c = inf y'-> X c = inf
Then the powerful ISAP template passes through the water.
Code:
#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std; #define INF 0x3f3f3f3f queue<int> q; #define N 3010#define M 20010struct Solver { int head[N << 1], next[(M << 2) + N*2], end[(M << 2) + N*2], flow[(M << 2) + N*2], ind; int gap[N << 1], stack[N << 1], top, cur[N << 1], d[N << 1]; void reset() { ind = top = 0; memset(head, -1, sizeof(head)); } void addedge(int a, int b, int _flow) { int q = ind++; end[q] = b; next[q] = head[a]; head[a] = q; flow[q] = _flow; } void make(int a, int b, int _flow) { //printf("%d %d %d\n", a, b, _flow); addedge(a, b, _flow); addedge(b, a, 0); } void make_db(int a, int b, int _flow) { addedge(a, b, _flow); addedge(b, a, _flow); } void bfs(int T) { memset(gap, 0, sizeof(gap)); memset(d, -1, sizeof(d)); ++gap[d[T] = 0]; q.push(T); int i, j; while(!q.empty()) { i = q.front(); q.pop(); for(j = head[i]; j != -1; j = next[j]) if (d[end[j]] == -1) { ++gap[d[end[j]] = d[i] + 1]; q.push(end[j]); } } } int Maxflow(int S, int T) { bfs(T); memcpy(cur, head, sizeof(cur)); int u = S, res = 0, Min, ins, i; bool find; while(d[S] < T - S + 1) { if (u == T) { Min = INF; for(i = 0; i < top; ++i) if (Min > flow[stack[i]]) Min = flow[stack[i]], ins = i; for(i = 0; i < top; ++i) flow[stack[i]] -= Min, flow[stack[i] ^ 1] += Min; res += Min; u = end[stack[top = ins] ^ 1]; } if (u != T && !gap[d[u] - 1]) break; find = 0; for(int &j = cur[u]; j != -1; j = next[j]) if (flow[j] && d[end[j]] + 1 == d[u]) { ins = j; find = 1; break; } if (find) { stack[top++] = ins; cur[u] = ins; u = end[ins]; } else { Min = T - S + 1; for(int j = head[u]; j != -1; j = next[j]) if (flow[j] && d[end[j]] < Min) { Min = d[end[j]]; cur[u] = j; } if (!--gap[d[u]]) break; ++gap[d[u] = Min + 1]; if (u != S) u = end[stack[--top] ^ 1]; } } return res; }}G; int get[N]; int main() { int n, m, num; scanf("%d%d%d", &n, &m, &num); int a, b, x; register int i, j; G.reset(); G.make(0, 1, INF); for(i = 1; i <= m; ++i) { scanf("%d%d", &a, &b); G.make(a * 2, b * 2 - 1, INF); G.make(b * 2, a * 2 - 1, INF); } while(num--) { scanf("%d", &x); get[x] = 1; } G.make(1, 2, INF); for(i = 2; i <= n; ++i) { if (!get[i]) G.make(2 * i - 1, 2 * i, 1); else G.make(2 * i - 1, 2 * i, INF), G.make(2 * i, 2 * n + 1, INF); } printf("%d", G.Maxflow(0, 2 * n + 1)); return 0;}
Bzoj1585 usaco 2009 Mar gold 3. Earthquake Damage 2