您的位置:首页 > 其它

hdu 3046 Pleasant sheep and big big wolf(最小割)

2015-12-23 17:02 483 查看
Pleasant sheep and big big wolf

时间限制2秒 内存限制64M

ProblemDescription

In BIT, there is a well-known prairie. And it attractspleasant sheep and his companions to have a holiday. Big big wolf and hisfamilies know about this, and quietly hid in the big lawn. As a BITer, we havean obligation to protect pleasant sheep and his companions
to free from beingdisturbed by big big wolf. We decided to build a number of unit fence whoselength is 1. Any wolf and sheep can not cross the fence. Of course, one gridcan only contain an animal.

Now, we ask to place the minimum fences to let pleasant sheep and hisCompanions to free from being disturbed by big big wolf and his companions.

1078

Input

There are many cases.

For every case:

N and M ( N,M<=200 )

then N*M matrix:

0 is empty, and 1 is pleasant sheep and his companions, 2 is big big wolf andhis companions.

Output

For every case:

First line output “Case p:”, p is the p-th case;

The second line is the answer.

SampleInput

4 6

1 0 0 1 0 0

0 1 1 0 0 0

2 0 0 0 0 0

0 2 0 1 1 0

SampleOutput

Case 1:

4

solution:

以狼为源点,羊为汇点,求最小割即为最少的围墙数。出源点和汇点外其余两个网格之间的权值都是1,表示有一头狼能够通过网格走到羊群中去。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define maxn 500000
#define INF 10000
int head[maxn], cur[maxn], d[maxn], st[maxn * 2], s, t, no;
int n, m;
struct point{
int  from, to, flow, next;
}p[maxn * 2];
void add(int u, int v, int z){
p[no].from = u; p[no].to = v; p[no].flow = z; p[no].next = head[u]; head[u] = no++;
p[no].from = v; p[no].to = u; p[no].flow = 0; p[no].next = head[v]; head[v] = no++;
}
void init(){
memset(head, -1, sizeof(head));
no = 0;
}
bool bfs(){
int i, x, y;
queue<int>q;
memset(d, -1, sizeof(d));
d[s] = 0;	q.push(s);
while (!q.empty()){
x = q.front();	q.pop();
for (i = head[x]; i != -1; i = p[i].next){
if (p[i].flow && d[y = p[i].to] < 0){
d[y] = d[x] + 1;
if (y == t)	return true;
q.push(y);
}
}
}
return false;
}
int dinic(){
int i, loc, top, x = s, nowflow, maxflow = 0;
while (bfs()){
for (i = s; i <= t; i++)cur[i] = head[i];
top = 0;
while (true){
if (x == t){
nowflow = INF;
for (i = 0; i < top; i++){
if (nowflow > p[st[i]].flow){
nowflow = p[st[i]].flow;
loc = i;
}
}
for (i = 0; i < top; i++){
p[st[i]].flow -= nowflow;
p[st[i] ^ 1].flow += nowflow;
}
maxflow += nowflow;
top = loc;	x = p[st[top]].from;
}
for (i = cur[x]; i != -1; i = p[i].next)
if (p[i].flow && d[p[i].to] == d[x] + 1) break;
cur[x] = i;
if (i != -1){
st[top++] = i;
x = p[i].to;
}
else {
if (!top)	break;
d[x] = -1;
x = p[st[--top]].from;
}
}
}
return maxflow;
}
int main()
{
int n, m, pos, i, j, x, cc = 1;
while (scanf("%d%d", &n, &m) != EOF)
{
init();
s = 0; t = n*m + 2;
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
{
scanf("%d", &x);
pos = (i - 1)*m + j;
if (i != 1)add(pos, pos - m, 1);
if (i != n)add(pos, pos + m, 1);
if (j != 1)add(pos, pos - 1, 1);
if (j != m)add(pos, pos + 1, 1);
if (x == 1)add(s, pos, INF);
else if (x == 2)add(pos, t, INF);
}
printf("Case %d:\n%d\n", cc++, dinic());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: