题目
“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......”
Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干!
Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。
通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。
Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。
【数据范围】
10%的数据 n,m≤3
30%的数据 n,m≤20
100%的数据 n,m≤100
题意
给你一个n*m的矩阵,让你求用尽量少的篱笆,把羊和狼分开。
分析
我们可以发现,这题的篱笆,就是把两个集合羊和狼)一分为二,而且又是费用最小,所以我们自然的想到了最小割。
我们接着考虑建图:
从源点向所有的狼连一条容量为maxlongint的边,然后再从所有的羊向汇点连一条容量为maxlongint的边,狼向周围的空地和羊连容量为1的边,空地往周围空地和羊连一条容量为1的边,这样跑一次最大流便可以了。
代码
varn,m,i,j,nu,x,y,t,s,k,ans:longint;bd:array[1..4,1..2] of longint=0,1),1,0),-1,0),0,-1));b,las,nex,f,re,d,dis:array[0..200000] of longint;a:array[1..100,1..100] of longint;
procedure insertx,y,z:longint);
beginincnu);b[nu]:=y;nex[nu]:=las[x];las[x]:=nu;f[nu]:=z;re[nu]:=nu+1;incnu);b[nu]:=x;nex[nu]:=las[y];las[y]:=nu;f[nu]:=0;re[nu]:=nu-1;
end;
function bfs:boolean;
var l,r,p:longint;
beginl:=0;r:=1;fillchardis,sizeofdis),0);dis[0]:=1;d[1]:=0;while l<r do beginincl);p:=las[d[l]];while p<>0 do beginif dis[b[p]]=0)andf[p]>0) then begindis[b[p]]:=dis[d[l]]+1;incr);d[r]:=b[p];end;p:=nex[p];end;end;exitdis[t]<>0);
end;
function minl,r:longint):longint;
beginif l<r then exitl);exitr);
end;
function dinicx,y:longint):longint;
var p,o:longint;
beginif x=t then exity);p:=las[x];dinic:=0;while p<>0 do beginif f[p]>0)anddis[b[p]]=dis[x]+1) then begino:=dinicb[p],miny,f[p]));if o<>0 then begindecf[p],o);incf[re[p]],o);decy,o);incdinic,o);if y=0 then break;end;end;p:=nex[p];end;
end;
beginreadlnn,m);for i:=1 to n do beginfor j:=1 to m do reada[i,j]);readln;end;for i:=1 to n dofor j:=1 to m do beginif a[i,j]=1 then insert0,i-1)*m+j,maxlongint)else if a[i,j]=2 then inserti-1)*m+j,n*m+1,maxlongint);if a[i,j]<>2 thenfor k:=1 to 4 do beginx:=i+bd[k,1];y:=j+bd[k,2];if x<1)ory<1)orx>n)ory>m) then continue;if a[x,y]<>1 then inserti-1)*m+j,x-1)*m+y,1);end;end;t:=n*m+1;while bfs do ans:=ans+dinic0,maxlongint);writelnans);
end.