浮云洲之战

浮云洲之战
(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.       
View Code
posted @ 2014-07-20 20:30  ZYF-ZYF  Views(249)  Comments(0Edit  收藏  举报