您的位置:首页 > 其它

【Codevs1034】家园(最大流,裂点)

2016-12-02 19:16 225 查看

题意:由于人类对自然的疯狂破坏,人们意识到在大约2300年之后,地球不能再居住了,于是在月球上建立了新的绿地,以便在需要时移民。令人意想不到的是,2177年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须在最短的时间内迁往月球。
现有n个太空站处于地球与月球之间(编号1..n),m艘公共交通太空船在其中来回穿梭,每个太空站Si可容纳无限的人,每艘太空船pi只可容纳Hpi人。对于每一艘太空船pi,将周期性地停靠一系列的太空站(Si1,Si2…Sir),如:(1,3,4)表示停靠太空站1 3 4 1 3 4 1 3 4 …。 任一艘太空船从任一个太空站驶往另一个任意的太空站耗时为1。人只能在太空船停靠太空站(或地球、月球)时上船或下船。初始时的人全在地球上,太空船全在初始站(太空船pi处于Si1),目标是让所有的人尽快地全部转移到月球上。

文件第一行为三个正整数 n(太空站个数)、 m(太空船个数)、 k(需要运送的地球上的人的个数),其中 1<=m<=13, 1<=n<=20, 1<=k<=50。

思路:按时间裂点跑最大流

num[i,j]表示i秒后的j点

(i,j)-->(i+1,j)连流量为无限边

(i,x)-->(i+1,y)连流量为h[k]的边,x,y为k号飞船分别在i,i+1时刻停留的星球

枚举答案并加边,dinic即可

注意每次最大流跑完后要把流量还原重构,改了很长时间没改出来

自己还是Too Simple

顺便说一句1999年的官方数据第二组是错的,正确答案是5,OUT是7

1 var head,vet,next,len,dis,gap,fan,h,r,save:array[0..100000]of longint;
2     a,b,num:array[0..110,0..110]of longint;
3     n,m,i,j,k,x,ans,tot,source,src,s:longint;
4
5 procedure add(a,b,c:longint);
6 begin
7  inc(tot);
8  next[tot]:=head[a];
9  vet[tot]:=b;
10  len[tot]:=c;
11  head[a]:=tot;
12 end;
13
14 function min(x,y:longint):longint;
15 begin
16  if x<y then exit(x);
17  exit(y);
18 end;
19
20 function dfs(u,aug:longint):longint;
21 var e,v,val,flow,t:longint;
22 begin
23  if u=src then exit(aug);
24  flow:=0;
25  e:=head[u]; val:=s-1;
26  while e<>0 do
27  begin
28   v:=vet[e];
29   if len[e]>0 then
30   begin
31    if dis[u]=dis[v]+1 then
32    begin
33     t:=dfs(v,min(len[e],aug-flow));
34     len[e]:=len[e]-t;
35     len[fan[e]]:=len[fan[e]]+t;
36     flow:=flow+t;
37     if dis[source]>=s then exit(flow);
38     if aug=flow then break;
39    end;
40    val:=min(val,dis[v]);
41   end;
42   e:=next[e];
43  end;
44  if flow=0 then
45  begin
46   dec(gap[dis[u]]);
47   if gap[dis[u]]=0 then dis[source]:=s;
48   dis[u]:=val+1;
49   inc(gap[dis[u]]);
50  end;
51  exit(flow);
52 end;
53
54 function maxflow:longint;
55 var ans:longint;
56 begin
57  fillchar(dis,sizeof(dis),0);
58  fillchar(gap,sizeof(gap),0);
59  gap[0]:=s;
60  ans:=0;
61  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
62  exit(ans);
63 end;
64
65 begin
66  assign(input,'codevs1034.in'); reset(input);
67  assign(output,'codevs1034.out'); rewrite(output);
68  readln(n,m,k);
69  for i:=0 to 101 do
70   for j:=1 to n+2 do
71   begin
72    inc(s); num[i,j]:=s;
73   end;
74  for i:=1 to m do
75  begin
76   read(h[i]); read(r[i]);
77   for j:=1 to r[i] do
78   begin
79    read(a[i,j]);
80    if a[i,j]=0 then a[i,j]:=n+1;
81    if a[i,j]=-1 then a[i,j]:=n+2;
82   end;
83   x:=1; b[i,0]:=a[i,1];
84   for j:=1 to 101 do
85   begin
86    inc(x); if x=r[i]+1 then x:=1;
87    b[i,j]:=a[i,x];
88   end;
89
90  end;
91  ans:=-1;
92  source:=num[0,n+1];
93
94  for i:=0 to 101 do
95  begin
96   for j:=1 to tot do save[j]:=len[j]; //重构边的容量,极其重要
97   src:=num[i,n+2]; s:=src;
98   if maxflow>=k then begin ans:=i; break; end;
99   for j:=1 to tot do len[j]:=save[j]; //重构边的容量,极其重要
100   for j:=1 to m do
101   begin
102    fan[tot+1]:=tot+2;
103    fan[tot+2]:=tot+1;
104    add(num[i,b[j,i]],num[i+1,b[j,i+1]],h[j]);
105  //  writeln(i,' ',b[j,i],' ',i+1,' ',b[j,i+1],' ',h[j]);
106    add(num[i+1,b[j,i+1]],num[i,b[j,i]],0);
107   // writeln(i+1,' ',b[j,i+1],' ',i,' ',b[j,i],' ',0);
108   end;
109   for j:=1 to n+2 do
110   begin
111    fan[tot+1]:=tot+2;
112    fan[tot+2]:=tot+1;
113    add(num[i,j],num[i+1,j],maxlongint);
114   // writeln(i,' ',j,' ',i+1,' ',j,' ',maxlongint);
115    add(num[i+1,j],num[i,j],0);
116   // writeln(i+1,' ',j,' ',i,' ',j,' ',0);
117   end;
118   writeln;
119  end;
120  if ans>0 then writeln(ans)
121   else writeln(0);
122  //close(input);
123  //close(output);
124 end.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: