cychester

BZOJ 1412[ZJOI2009]狼和羊的故事 - 最小割

题解

源点$S$连向狼的领地, 羊的领地连向汇点$T$, 再从每个位置连向相邻的位置。

跑一边最大流就可以的出答案

 

代码

 

 1 #include<cstring>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 #define rd read()
 7 #define rep(i,a,b) for( int i = (a); i <= (b); ++i)
 8 #define per(i,a,b) for(int i = (a); i >= (b); --i)
 9 using namespace std;
10   
11 const int N = 5e4, inf = ~0U >> 2;
12 int head[N], S, T, dep[N], tot, n, m, mp[105][105], ans;
13 int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
14   
15 queue<int> q;
16   
17 struct edge {
18      int nxt, to, val;
19 }e[N << 2];
20   
21 int read() {
22     int X = 0, p = 1;char c = getchar();
23     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = - 1;
24     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
25     return X * p;
26 }
27   
28 int ch(int x) {
29     return ((x + 1) ^ 1) - 1;
30 }
31   
32 int tn(int x, int y) {
33     return (x - 1) * m + y;
34 }
35   
36 void added(int fr, int to, int val) {
37     e[++tot].to = to;
38     e[tot].val = val;
39     e[tot].nxt = head[fr];
40     head[fr] = tot;
41 }
42   
43 void add(int fr, int to, int val) {
44     added(fr, to, val);
45     added(to, fr, 0);
46 }
47   
48 int bfs() {
49     memset(dep, 0, sizeof(dep));
50     dep[S] = 1;
51     q.push(S);
52     for(int u, nt; !q.empty(); ) {
53         u = q.front(); q.pop();
54         for(int i = head[u]; i; i = e[i].nxt ) {
55             nt = e[i].to;
56             if(dep[nt] || !e[i].val) continue;
57             dep[nt] = dep[u] + 1;
58             q.push(nt);
59         }
60     }
61     return dep[T];
62 }
63   
64 int dfs(int u, int flow) {
65     if(u == T) return flow;
66     if(!flow) return 0;
67     int add = 0;
68     for(int i = head[u]; i && add < flow; i = e[i].nxt) {
69         int nt = e[i].to;
70         if(dep[nt] != dep[u] + 1 || !e[i].val) continue;
71         int tmp = dfs(nt, min(flow - add, e[i].val));
72         add += tmp;
73         e[i].val -= tmp;
74         e[ch(i)].val += tmp;
75     }
76     return add;
77 }
78   
79 int main()
80 {
81     n = rd; m = rd;
82     T = n * m * 3;
83     rep(i, 1, n) rep(j, 1, m) {
84         mp[i][j] = rd;
85         if(mp[i][j] == 1) add(S, tn(i, j), inf);
86         if(mp[i][j] == 2) add(tn(i, j), T, inf);
87     }
88     rep(i, 1, n) rep(j, 1, m) rep(k, 0, 3) {
89         int nx = i + dx[k], ny = j + dy[k];
90         if(!nx || !ny || nx > n || ny > m) continue;
91         add(tn(i, j), tn(nx, ny), 1);
92     }
93     for(; bfs(); ) ans += dfs(S, inf);
94     printf("%d\n", ans);
95 }
View Code

 

posted on 2018-08-19 20:30  cychester  阅读(131)  评论(0编辑  收藏  举报

导航