• bzoj1797


    其实我觉得这种题目风格很像今天省选第三轮D1T1

    都是在一个算法模型上去探索规律;

    首先我们要做一遍最大流毫无疑问

    第一问看起来很好想,只要是满流边就可以了?

    错,反例不难找到

    如:1--->2 flow 4

    2--->3 flow 4

    3--->1 flow 4

    1--->4 flow 4

    很有可能我们在找增广路的时候,走了多余的回路(1-2-3-1),导致前3条边也是满流边,但不会出现在最小割方案中

    所以我们考虑用tarjan对残留网络缩点;

    对于第一问,要求是满流边且起点终点在不同集合

    第二问,显然在满足第一问的前提下,起点终点分属源点汇点集合

      1 const inf=100000007;
      2 type node=record
      3        from,point,next,flow:longint;
      4      end;
      5 
      6 var edge:array[0..130000] of node;
      7     ans1,ans2:array[0..60010] of longint;
      8     p,cur,pre,numh,h,low,dfn,be,st:array[0..5010] of longint;
      9     tot,d,r,x,y,z,i,j,n,m,s,t,len:longint;
     10     v,f:array[0..5010] of boolean;
     11 
     12 function min(a,b:longint):longint;
     13   begin
     14     if a>b then exit(b) else exit(a);
     15   end;
     16 
     17 procedure add(x,y,f:longint);
     18   begin
     19     inc(len);
     20     edge[len].point:=y;
     21     edge[len].from:=x;
     22     edge[len].flow:=f;
     23     edge[len].next:=p[x];
     24     p[x]:=len;
     25   end;
     26 
     27 procedure sap;
     28   var u,i,j,tmp,neck,q:longint;
     29   begin
     30     u:=s;
     31     numh[0]:=n;
     32     while h[s]<n do
     33     begin
     34       if u=t then
     35       begin
     36         i:=s;
     37         neck:=inf;
     38         while i<>t do
     39         begin
     40           j:=cur[i];
     41           if neck>edge[j].flow then
     42           begin
     43             neck:=edge[j].flow;
     44             q:=i;
     45           end;
     46           i:=edge[j].point;
     47         end;
     48         i:=s;
     49         while i<>t do
     50         begin
     51           j:=cur[i];
     52           dec(edge[j].flow,neck);
     53           inc(edge[j xor 1].flow,neck);
     54           i:=edge[j].point;
     55         end;
     56         u:=q;
     57       end;
     58       q:=-1;
     59       i:=p[u];
     60       while i<>-1 do
     61       begin
     62         j:=edge[i].point;
     63         if (edge[i].flow>0) and (h[u]=h[j]+1) then
     64         begin
     65           q:=i;
     66           break;
     67         end;
     68         i:=edge[i].next;
     69       end;
     70       if q<>-1 then
     71       begin
     72         cur[u]:=q;
     73         pre[j]:=u;
     74         u:=j;
     75       end
     76       else begin
     77         dec(numh[h[u]]);
     78         if numh[h[u]]=0 then exit;
     79         tmp:=n;
     80         i:=p[u];
     81         while i<>-1 do
     82         begin
     83           j:=edge[i].point;
     84           if edge[i].flow>0 then tmp:=min(tmp,h[j]);
     85           i:=edge[i].next;
     86         end;
     87         h[u]:=tmp+1;
     88         inc(numh[h[u]]);
     89         if u<>s then u:=pre[u];
     90       end;
     91     end;
     92   end;
     93 
     94 procedure tarjan(x:longint);
     95   var i,y:longint;
     96   begin
     97     v[x]:=true;
     98     f[x]:=true;
     99     inc(r);
    100     inc(d);
    101     st[r]:=x;
    102     dfn[x]:=d;
    103     low[x]:=d;
    104     i:=p[x];
    105     while i<>-1 do
    106     begin
    107       y:=edge[i].point;
    108       if edge[i].flow>0 then
    109       begin
    110         if not v[y] then
    111         begin
    112           tarjan(y);
    113           low[x]:=min(low[x],low[y]);
    114         end
    115         else if f[y] then
    116           low[x]:=min(low[x],low[y]);
    117       end;
    118       i:=edge[i].next;
    119     end;
    120     if low[x]=dfn[x] then
    121     begin
    122       inc(tot);
    123       while st[r+1]<>x do
    124       begin
    125         y:=st[r];
    126         f[y]:=false;
    127         be[y]:=tot;
    128         dec(r);
    129       end;
    130     end;
    131   end;
    132 
    133 begin
    134   readln(n,m,s,t);
    135   len:=-1;
    136   fillchar(p,sizeof(p),255);
    137   for i:=1 to m do
    138   begin
    139     readln(x,y,z);
    140     add(x,y,z);
    141     add(y,x,0);
    142   end;
    143   sap;
    144   for i:=1 to n do
    145     if not v[i] then
    146     begin
    147       r:=0;
    148       d:=0;
    149       tarjan(i);
    150     end;
    151   i:=0;
    152   while i<=len do
    153   begin
    154     if (edge[i].flow=0) then
    155     begin
    156       x:=edge[i].from;
    157       y:=edge[i].point;
    158       if be[x]<>be[y] then
    159       begin
    160         ans1[i div 2+1]:=1;
    161         if (be[x]=be[s]) and (be[y]=be[t]) or (be[x]=be[t]) and (be[y]=be[s]) then
    162           ans2[i div 2+1]:=1;
    163       end;
    164     end;
    165     i:=i+2;
    166   end;
    167   for i:=1 to m do
    168     writeln(ans1[i],' ',ans2[i]);
    169 end.
    View Code
  • 相关阅读:
    怎么写好组件
    html5/css3常考面试题
    js各种继承方式和优缺点的介绍
    C#控件背景透明的几种解决方案
    c# 控件闪烁处理方法
    使用委托的BeginInvoke方法来完成复杂任务的操作
    C#中的预处理器指令
    C#中父窗口和子窗口之间实现控件互操作
    C#编程让Outlook乖乖交出帐户密码
    在Linux上运行C#
  • 原文地址:https://www.cnblogs.com/phile/p/4473230.html
Copyright © 2020-2023  润新知