zoukankan      html  css  js  c++  java
  • 【BZOJ3504】危桥(最大流)

    题意:见题面

    思路:http://www.cnblogs.com/chenyushuo/p/5139556.html

    必须交换b1,b2做第二次最大流的原因:

    假如一个a1到b2的一个流和b1到a2的一个流分别经过了一个桥的两个端点(u,v),如图

    我们就可以将a1到b2的流量改为经过u-v-a2-T到达T,同理将b1到a2的流量改为经过v-u-b2-T到达T,这样就说明这个流是没有问题的
    在这种情况下将b1和b2交换后,流量显然不会有变化
    如果一个a1到b2的一个流和b1到a2的一个流没有经过任何一个桥的两个端点,这个流显然不合法,且在b1和b2交换后,流量会减小
      1 var fan:array[1..200000]of longint;
      2     head,vet,next,gap,len,dis:array[0..50000]of longint;
      3     a:array[1..100,1..100]of char;
      4     ch:string;
      5     n,m,i,tot,x1,x2,y1,y2,s1,s2,src,source,s,j:longint;
      6     flag:boolean;
      7 
      8 function min(x,y:longint):longint;
      9 begin
     10  if x<y then exit(x);
     11  exit(y);
     12 end;
     13 
     14 procedure add(a,b,c:longint);
     15 begin
     16  inc(tot);
     17  next[tot]:=head[a];
     18  vet[tot]:=b;
     19  len[tot]:=c;
     20  head[a]:=tot;
     21 
     22  inc(tot);
     23  next[tot]:=head[b];
     24  vet[tot]:=a;
     25  len[tot]:=0;
     26  head[b]:=tot;
     27 end;
     28 
     29 function dfs(u,aug:longint):longint;
     30 var e,v,t,val,flow:longint;
     31 begin
     32  if u=src then exit(aug);
     33  e:=head[u]; flow:=0; val:=s-1;
     34  while e<>0 do
     35  begin
     36   v:=vet[e];
     37   if len[e]>0 then
     38   begin
     39    if dis[u]=dis[v]+1 then
     40    begin
     41     t:=dfs(v,min(len[e],aug-flow));
     42     len[e]:=len[e]-t;
     43     len[fan[e]]:=len[fan[e]]+t;
     44     flow:=flow+t;
     45     if dis[source]>=s then exit(flow);
     46     if aug=flow then break;
     47    end;
     48    val:=min(val,dis[v]);
     49   end;
     50   e:=next[e];
     51  end;
     52  if flow=0 then
     53  begin
     54   dec(gap[dis[u]]);
     55   if gap[dis[u]]=0 then dis[source]:=s;
     56   dis[u]:=val+1;
     57   inc(gap[dis[u]]);
     58  end;
     59  exit(flow);
     60 end;
     61 
     62 function maxflow:longint;
     63 var ans:longint;
     64 begin
     65  fillchar(gap,sizeof(gap),0);
     66  fillchar(dis,sizeof(dis),0);
     67  gap[0]:=s; ans:=0;
     68  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
     69  exit(ans);
     70 end;
     71 
     72 procedure build;
     73 var i,j:longint;
     74 begin
     75  for i:=1 to n do
     76   for j:=1 to n do
     77   begin
     78    if a[i,j]='O' then add(i,j,2);
     79    if a[i,j]='N' then add(i,j,maxlongint);
     80   end;
     81 end;
     82 
     83 begin
     84  assign(input,'bzoj3504.in'); reset(input);
     85  assign(output,'bzoj3504.out'); rewrite(output);
     86  for i:=1 to 200000 do
     87   if i mod 2=1 then fan[i]:=i+1
     88    else fan[i]:=i-1;
     89  while not eof do
     90  begin
     91   readln(n,x1,y1,s1,x2,y2,s2);
     92   if n=0 then break;
     93   inc(x1); inc(y1); inc(x2); inc(y2);
     94   tot:=0; for i:=1 to n+2 do head[i]:=0;
     95   for i:=1 to n do
     96   begin
     97    readln(ch);
     98    for j:=1 to n do a[i,j]:=ch[j];
     99   end;
    100   s:=n; source:=s+1; src:=s+2; s:=s+2;
    101   build;
    102   add(source,x1,2*s1);
    103   add(source,x2,2*s2);
    104   add(y1,src,2*s1);
    105   add(y2,src,2*s2);
    106   flag:=true;
    107   if maxflow<2*(s1+s2) then flag:=false;
    108   if flag then
    109   begin
    110    tot:=0; for i:=1 to n+2 do head[i]:=0;
    111    build;
    112    add(source,x1,2*s1);
    113    add(source,y2,2*s2);
    114    add(y1,src,2*s1);
    115    add(x2,src,2*s2);
    116    if maxflow<2*(s1+s2) then flag:=false;
    117   end;
    118   if flag then writeln('Yes')
    119    else writeln('No');
    120  end;
    121  close(input);
    122  close(output);
    123 end.
     
  • 相关阅读:
    分页SQL 和Oracle 存储过程
    什么是SilverLight
    opendpi 源码分析(一)
    Multiway arrays
    循环链表
    轮询算法 这是一个印度人写的,学习下。 来自 codeproject
    Friday the Thirteenth
    通过命令行指定监听的IP和端口
    pthread_key_t
    贝叶斯网络 未学习前数据结构
  • 原文地址:https://www.cnblogs.com/myx12345/p/6204113.html
Copyright © 2011-2022 走看看