您的位置:首页 > 产品设计 > UI/UE

【POJ3498】March of the Penguins(最大流,裂点)

2016-12-02 20:26 309 查看

题意:在靠近南极的某处,一些企鹅站在许多漂浮的冰块上。由于企鹅是群居动物,所以它们想要聚集到一起,在同一个冰块上。企鹅们不想把自己的身体弄湿,所以它们在冰块之间跳跃,但是它们的跳跃距离,有一个上限。 
随着气温的升高,冰块开始融化,并出现了裂痕。而企鹅跳跃的压力,使得冰块的破裂加速。幸运的是,企鹅对冰块十分有研究,它们能知道每块冰块最多能承受多少次跳跃。对冰块的损害只在跳起的时候产生,而落地时并不对其产生伤害。 
现在让你来帮助企鹅选择一个冰面使得它们可以聚集到一起。

第一行整数N,和浮点数D,表示冰块的数目和企鹅的最大跳跃距离。 

(1≤N ≤100) (0 ≤D ≤100 000), 
接下来N行,xi, yi, ni and mi,分别表示冰块的X和Y坐标,该冰块上的企鹅数目,以及还能承受起跳的次数。 

输出所有可能的相聚冰块的编号,以0开始。如果不能相遇,输出-1。

思路:这道题是一年前上课最大流的例题,如果去年就拿了一等多好

        考虑强行限制起跳次数很难,尝试裂点

        将每块冰都裂成两个点(i,1),(i,2)

        (i,1)-->(i,2)连流量为m[i]的边

        对于原来在冰面上的企鹅,建立超级源S

         s-->(i,1)连流量为n[i]的边 

        对于平面距离小于D的两点i,j

        (i,2)-->(j,1)连流量为maxlongint的边

        枚举(j,1)作为汇点判断最大流量是否>=企鹅总数即可

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

 

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