1412: [ZJOI2009]狼和羊的故事

来源:互联网 发布:漫画配音软件 编辑:程序博客网 时间:2024/05/17 04:55

1412: [ZJOI2009]狼和羊的故事

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2562  Solved: 1320
[Submit][Status][Discuss]

Description

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

Input

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

Output

文件中仅包含一个整数ans,代表篱笆的最短长度。

Sample Input

2 2
2 2
1 1

Sample Output

2

数据范围
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100

HINT

Source

[Submit][Status][Discuss]



建篱笆隔离狼群&&羊群

=>把图中的点集分成两种

建立一个源点向所有狼连INF的边

所有羊向汇点连INF的边

同种生物之间的边可以舍去啦

跑一遍最大流求出最小割

#include<iostream>#include<cstdio>#include<queue>#include<vector>#include<bitset>#include<algorithm>#include<cstring>#include<map>#include<stack>#include<set>#include<cmath>#include<ext/pb_ds/priority_queue.hpp>using namespace std;const int maxn = 101;const int maxm = 1E4 + 10;const int INF = ~0U>>1;const int dx[4] = {1,0,-1,0};const int dy[4] = {0,1,0,-1};struct E{int to,cap,flow;E(){}E(int to,int cap,int flow): to(to),cap(cap),flow(flow){}}edgs[maxm*20];int n,m,tot,cnt,Cnt,s,t,L[maxm],vis[maxm],p[maxn][maxn],cur[maxm];queue <int> Q;vector <int> v[maxm];void Add(int x,int y,int w){v[x].push_back(cnt); edgs[cnt++] = E(y,w,0);v[y].push_back(cnt); edgs[cnt++] = E(x,0,0);}bool BFS(){vis[s] = ++Cnt; L[s] = 1; Q.push(s);while (!Q.empty()) {int k = Q.front(); Q.pop();for (int i = 0; i < v[k].size(); i++) {E e = edgs[v[k][i]];if (e.cap == e.flow) continue;if (vis[e.to] == Cnt) continue;vis[e.to] = Cnt;L[e.to] = L[k] + 1;Q.push(e.to);}}return vis[t] == Cnt;}int Dicnic(int x,int a){if (x == t || !a) return a;int flow = 0;for (int &i = cur[x]; i < v[x].size(); i++) {E &e = edgs[v[x][i]];if (e.cap == e.flow) continue;if (L[e.to] != L[x] + 1) continue;int f = Dicnic(e.to,min(a,e.cap - e.flow));if (!f) continue;flow += f;e.flow += f;edgs[v[x][i]^1].flow -= f;a -= f;if (!a) return flow;}if (!flow) L[x] = -1;return flow;}int main(){#ifdef DMCfreopen("DMC.txt","r",stdin);#endifcin >> n >> m;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)scanf("%d",&p[i][j]);s = 0; t = n*m + 1;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++) {if (p[i][j] == 1) Add(s,m*(i-1)+j,INF);else if (p[i][j] == 2) Add(m*(i-1)+j,t,INF);for (int l = 0; l < 4; l++) {int xx = i + dx[l];int yy = j + dy[l];if (!xx || xx > n || !yy || yy > m) continue;if (p[xx][yy] && p[xx][yy] == p[i][j]) continue;Add(m*(i-1)+j,m*(xx-1)+yy,1);}}int MaxFlow = 0;while (BFS()) {for (int i = s; i <= t; i++) cur[i] = 0;MaxFlow += Dicnic(s,INF);}cout << MaxFlow;return 0;}


0 0
原创粉丝点击