洛谷P13445 [USACO5.4]奶牛的电信Telecowmunication(网络流)
题目描述
农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。
很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。
有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。
以如下网络为例:
1*
/
3 - 2*
这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。
输入输出格式
输入格式:
第一行 四个由空格分隔的整数:N,M,c1,c2.N是电脑总数(1<=N<=100),电脑由1到N编号。M是电脑之间连接的总数(1<=M<=600)。最后的两个整数c1和c2是上述两头奶牛使用的电脑编号。连接没有重复且均为双向的(即如果c1与c2相连,那么c2与c1也相连)。两台电脑之间至多有一条连接。电脑c1和c2不会直接相连。
第2到M+1行 接下来的M行中,每行包含两台直接相连的电脑的编号。
输出格式:
一个整数表示使电脑c1和c2不能互相通信需要坏掉的电脑数目的最小值。
输入输出样例
输入样例#1:
3 2 1 2
1 3
2 3
输出样例#1:
1
题解:
把一个点拆成两个点,连上容量为1的边,然后把其他边连一连求一下最小割就好了。
刚开始求c1的入点到c2的出点的最小割了,WA了一发,其实是求c1的出点到c2的汇点的最小割。要注意。
1 program rrr(input,output); 2 const 3 inf=123456789; 4 type 5 etype=record 6 t,c,next,rev:longint; 7 end; 8 var 9 e:array[0..5000]of etype; 10 a,d,cur:array[-660..660]of longint; 11 q:array[0..1222]of longint; 12 n,m,c1,c2,i,x,y,cnt,ans,h,t:longint; 13 function min(a,b:longint):longint; 14 begin 15 if a<b then exit(a) else exit(b); 16 end; 17 procedure ins(x,y,c:longint); 18 begin 19 inc(cnt);e[cnt].t:=y;e[cnt].c:=c;e[cnt].next:=a[x];a[x]:=cnt; 20 end; 21 procedure add(x,y,c:longint); 22 begin 23 ins(x,y,c);e[cnt].rev:=cnt+1;ins(y,x,0);e[cnt].rev:=cnt-1; 24 end; 25 procedure bfs; 26 begin 27 for i:=-n to n do d[i]:=-1; 28 h:=0;t:=1;q[1]:=c1;d[c1]:=0; 29 while h<t do 30 begin 31 inc(h);i:=a[q[h]]; 32 while i<>0 do 33 begin 34 if (d[e[i].t]=-1) and (e[i].c>0) then 35 begin 36 d[e[i].t]:=d[q[h]]+1; 37 inc(t);q[t]:=e[i].t; 38 end; 39 i:=e[i].next; 40 end; 41 end; 42 end; 43 function dfs(k,f:longint):longint; 44 var 45 ans,i,r:longint; 46 begin 47 if (k=-c2) or (f=0) then exit(f); 48 ans:=0;i:=cur[k]; 49 while i<>0 do 50 begin 51 if (d[e[i].t]=d[k]+1) and (e[i].c>0) then 52 begin 53 r:=dfs(e[i].t,min(f,e[i].c)); 54 dec(e[i].c,r);inc(e[e[i].rev].c,r); 55 dec(f,r);inc(ans,r); 56 if f=0 then break; 57 end; 58 i:=e[i].next;cur[k]:=i; 59 end; 60 if f>0 then d[k]:=-1; 61 exit(ans); 62 end; 63 begin 64 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output); 65 readln(n,m,c1,c2); 66 fillchar(a,sizeof(a),0);cnt:=0; 67 for i:=1 to n do add(-i,i,1); 68 for i:=1 to m do begin read(x,y);add(x,-y,inf);add(y,-x,inf); end; 69 ans:=0; 70 while true do 71 begin 72 bfs; 73 if d[-c2]=-1 then break; 74 for i:=-n to n do cur[i]:=a[i]; 75 ans:=ans+dfs(c1,inf); 76 end; 77 write(ans); 78 close(input);close(output); 79 end.