bzoj1001 狼抓兔子
bzoj1412 狼抓羊。。。
什么时候来个狼抓青蛙
狼爪喜羊羊。。。
都是最小割。。。
一个经典的最小割模型
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
int a[110][110];
struct edge {
int v,f,next;
}e[50010];
int cnt = -1,head[10010];
int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}
int cal (int i,int j) {
return (i - 1) * m + j;
}
void adde (int u,int v,int f) {
e[++cnt].v = v;
e[cnt].f = f;
e[cnt].next = head[u];
head[u] = cnt;
e[++cnt].v = u;
e[cnt].f = f;
e[cnt].next = head[v];
head[v] = cnt;
}
int depth[10010];
queue<int>q;
bool bfs () {
memset(depth,-1,sizeof depth);
while(!q.empty())
q.pop();
depth[0] = 1;
q.push(0);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(depth[v] != -1 || !e[i].f)
continue;
depth[v] = depth[u] + 1;
if(v == n * m + 1)
return 1;
q.push(v);
}
}
return 0;
}
int dfs (int u,int maxf) {
if(u == n * m + 1)
return maxf;
int leftf = maxf;
for(int i = head[u];i != -1;i = e[i].next) {
if(!leftf)
return maxf;
int v = e[i].v;
if(depth[v] != depth[u] + 1 || !e[i].f)
continue;
int t = dfs(v,min(leftf,e[i].f));
leftf -= t;
e[i].f -= t;
e[i ^ 1].f += t;
}
depth[u] = -1;
return maxf - leftf;
}
int main () {
memset(head,-1,sizeof head);
n = read_int();
m = read_int();
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
a[i][j] = read_int();
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j) {
if(a[i][j] == 1)
adde(0,cal(i,j),0x3f3f3f3f);
if(a[i][j] == 2)
adde(cal(i,j),n * m + 1,0x3f3f3f3f);
if(i + 1 <= n && (a[i + 1][j] != a[i][j] || (a[i + 1][j] == a[i][j] && a[i + 1][j] == 0)))
adde(cal(i,j),cal(i + 1,j),1);
if(j + 1 <= m && (a[i][j + 1] != a[i][j] || (a[i][j + 1] == a[i][j] && a[i][j + 1] == 0)))
adde(cal(i,j),cal(i,j + 1),1);
}
int ans = 0;
while(bfs()) {
ans += dfs(0,0x3f3f3f3f);
}
printf("%d\n",ans);
}