浮云洲之战
浮云洲之战
(seawar.pas/c/cpp)
题目描述
浮云洲是东海岸畔一个风景如画的小岛,信仰海神的渔民们在此世代捕鱼为生。浮云洲
的领导者被称为司卜,掌管岛上的大事,鲁明星就是司卜家的女儿。与浮云洲的居民一样,
鲁明星天生有着对大自然无比的热爱和对小动物的怜悯,但与大家不同的是,小小的她早已
踏遍各地河山,有着面对危险时勇敢果断的号召力和战斗精神。在游历的过程中,鲁明星认
识了精通兵法、武艺超群的豪侠管毅。意趣相投的两人结伴而行,共同来到了浮云洲。此时
恰逢海贼入侵浮云洲,面对软弱的岛民们,鲁明星坚决担负起了组织击退入侵者的重任。
浮云洲的村庄之间通过单向道路连接,构成一个有向无环图。如果在某个村庄安排了守
卫,那么这个守卫可以沿着某一条从这个村庄出发的路径走下去,在路径上的所有道路上安
放战斗设施。现在鲁明星想知道,要想使所有的道路都被安放战斗设施,最少需要多少名守
卫?
输入格式
第一行一个整数 n,表示浮云洲里村庄的个数。
接下来 n 行,每行的第一个数是一个整数,其中第 i+1 行的数是 di,表示从村庄 i 出发
有 di 条道路。每行紧接着会有 di 个整数,表示这些道路到达的村庄。
输出格式
一个整数 ans,表示最少需要的守卫人数。
样例输入
8
1 3
1 7
2 4 5
1 8
1 8
0
2 6 5
0
样例输出
4
数据范围与约定
对于 30% 的数据,满足 2<=n<=10。
对于 100% 的数据,满足 2<=n<=100,0<=di<n,没有重边和自环。
题解:
当时对网络流还不熟悉,后来一反应,这不是一个裸的有下界最小流吗,可惜我当时想到也不会求……
具体方法见我下一篇博文
代码:
1 const inf=maxlongint; 2 type node=record 3 from,go,next,v:longint; 4 end; 5 var tot,i,j,n,m,maxflow,l,r,s,t,x,y,ans,ss,tt:longint; 6 h,head,q,cur,indeg,outdeg:array[0..500] of longint; 7 e:array[0..50000] of node; 8 function min(x,y:longint):longint; 9 begin 10 if x<y then exit(x) else exit(y); 11 end; 12 procedure ins(x,y,z:longint); 13 begin 14 inc(tot); 15 e[tot].from:=x;e[tot].go:=y;e[tot].v:=z;e[tot].next:=head[x];head[x]:=tot; 16 end; 17 procedure insert(x,y,z:longint); 18 begin 19 ins(x,y,z);ins(y,x,0); 20 end; 21 function bfs:boolean; 22 var i,x,y:longint; 23 begin 24 fillchar(h,sizeof(h),0); 25 l:=0;r:=1;q[1]:=s;h[s]:=1; 26 while l<r do 27 begin 28 inc(l); 29 x:=q[l]; 30 i:=head[x]; 31 while i<>0 do 32 begin 33 y:=e[i].go; 34 if (e[i].v<>0) and (h[y]=0) then 35 begin 36 h[y]:=h[x]+1; 37 inc(r);q[r]:=y; 38 end; 39 i:=e[i].next; 40 end; 41 end; 42 exit (h[t]<>0); 43 end; 44 function dfs(x,f:longint):longint; 45 var i,y,used,tmp:longint; 46 begin 47 if x=t then exit(f); 48 used:=0; 49 i:=cur[x]; 50 while i<>0 do 51 begin 52 y:=e[i].go; 53 if (h[y]=h[x]+1) and (e[i].v<>0) then 54 begin 55 tmp:=dfs(y,min(e[i].v,f-used)); 56 dec(e[i].v,tmp);if e[i].v<>0 then cur[x]:=i; 57 inc(e[i xor 1].v,tmp); 58 inc(used,tmp); 59 if used=f then exit(f); 60 end; 61 i:=e[i].next; 62 end; 63 if used=0 then h[x]:=-1; 64 exit(used); 65 end; 66 procedure dinic; 67 begin 68 while bfs do 69 begin 70 for i:=0 to n+3 do cur[i]:=head[i]; 71 inc(maxflow,dfs(s,inf)); 72 end; 73 end; 74 procedure init; 75 begin 76 tot:=1; 77 readln(n); 78 s:=0;t:=n+1; 79 ss:=n+2;tt:=n+3; 80 for i:=1 to n do 81 begin 82 read(outdeg[i]); 83 for j:=1 to outdeg[i] do 84 begin 85 read(x); 86 inc(indeg[x]); 87 insert(i,x,inf); 88 insert(i,tt,1); 89 insert(ss,x,1); 90 end; 91 end; 92 for i:=1 to n do 93 begin 94 if indeg[i]=0 then insert(s,i,inf); 95 if outdeg[i]=0 then insert(i,t,inf); 96 end; 97 insert(t,s,inf); 98 end; 99 procedure main; 100 begin 101 s:=ss;t:=tt; 102 maxflow:=0; 103 dinic; 104 ans:=e[tot].v; 105 e[tot].v:=0;e[tot xor 1].v:=0; 106 s:=n+1;t:=0; 107 maxflow:=0; 108 dinic; 109 writeln(ans-maxflow); 110 end; 111 begin 112 assign(input,'input.txt');assign(output,'output.txt'); 113 reset(input);rewrite(output); 114 init; 115 main; 116 close(input);close(output); 117 end.