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


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

    第一行整数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.
  • 相关阅读:
    MariaDB Spider 数据库分库分表实践
    Kubernetes 集群日志 和 EFK 架构日志方案
    Kubernetes 集群和应用监控方案的设计与实践
    java wait(long timeout, int nanos),后面的nanos有什么用?
    如何对消息队列进行选型
    Java 设计模式笔记
    [译]为什么你应该关注 Docker
    Java 设计模式课堂作业记录
    AtCoder Beginner Contest 242(C~E)
    Denso Create Programming Contest 2022(AtCoder Beginner Contest 239) E~F 题
  • 原文地址:https://www.cnblogs.com/myx12345/p/6127244.html
Copyright © 2020-2023  润新知