zoukankan      html  css  js  c++  java
  • bzoj2893

    有起点终点的限制的路径覆盖
    首先tarjan缩点成DAG
    似乎不能按照二分匹配的做法做
    那么建立源汇拆点i,i',这两点之间连一条下界为1上界无穷的边,
    其它边都是下界为0,上界正无穷
    然后就是有源有汇的最小流,之前在bzoj2502介绍过

      1 const inf=10000007;
      2 type node=record
      3        po,flow,next:longint;
      4      end;
      5 
      6 var w,e:array[0..200010] of node;
      7     be,p,q,c,dfn,low,cur,a,b:array[0..2010] of longint;
      8     v,f:array[0..2010] of boolean;
      9     na,nb,h,ss,tt,t,te,s,len,n,m,i,x,y,j:longint;
     10 
     11 function min(a,b:longint):longint;
     12   begin
     13     if a>b then exit(b) else exit(a);
     14   end;
     15 
     16 procedure add(x,y:longint);
     17   begin
     18     inc(len);
     19     w[len].po:=y;
     20     w[len].next:=q[x];
     21     q[x]:=len;
     22   end;
     23 
     24 procedure build(x,y,f:longint);
     25   begin
     26     inc(len);
     27     e[len].po:=y;
     28     e[len].flow:=f;
     29     e[len].next:=p[x];
     30     p[x]:=len;
     31   end;
     32 
     33 procedure tarjan(x:longint);
     34   var i,y:longint;
     35   begin
     36     inc(h);
     37     dfn[x]:=h;
     38     low[x]:=h;
     39     v[x]:=true;
     40     inc(t);
     41     c[t]:=x;
     42     f[x]:=true;
     43     i:=q[x];
     44     while i<>0 do
     45     begin
     46       y:=w[i].po;
     47       if not v[y] then
     48       begin
     49         tarjan(y);
     50         low[x]:=min(low[x],low[y]);
     51       end
     52       else if f[y] then low[x]:=min(low[x],low[y]);
     53       i:=w[i].next;
     54     end;
     55     if low[x]=dfn[x] then
     56     begin
     57       inc(s);
     58       while c[t+1]<>x do
     59       begin
     60         y:=c[t];
     61         be[y]:=s;
     62         f[y]:=false;
     63         dec(t);
     64       end;
     65     end;
     66   end;
     67 
     68 procedure sap(s,t:longint);
     69   var q,u,i,j,tmp:longint;
     70   begin
     71     fillchar(c,sizeof(c),0);
     72     fillchar(dfn,sizeof(dfn),0);
     73     for i:=0 to t do
     74       cur[i]:=p[i];
     75     u:=s;
     76     dfn[0]:=t+1;
     77     while c[s]<t+1 do
     78     begin
     79       i:=cur[u];
     80       while i<>-1 do
     81       begin
     82         j:=e[i].po;
     83         if (e[i].flow>0) and (c[u]=c[j]+1) then
     84         begin
     85           cur[u]:=i;
     86           low[j]:=u;
     87           u:=j;
     88           if u=t then
     89           begin
     90             while u<>s do
     91             begin
     92               u:=low[u];
     93               j:=cur[u];
     94               dec(e[j].flow);
     95               inc(e[j xor 1].flow);
     96             end;
     97           end;
     98           break;
     99         end;
    100         i:=e[i].next;
    101       end;
    102       if i=-1 then
    103       begin
    104         dec(dfn[c[u]]);
    105         if dfn[c[u]]=0 then exit;
    106         q:=-1;
    107         tmp:=t;
    108         i:=p[u];
    109         while i<>-1 do
    110         begin
    111           j:=e[i].po;
    112           if e[i].flow>0 then
    113             if c[j]<tmp then
    114             begin
    115               q:=i;
    116               tmp:=c[j];
    117             end;
    118           i:=e[i].next;
    119         end;
    120         cur[u]:=q;
    121         c[u]:=tmp+1;
    122         inc(dfn[c[u]]);
    123         if u<>s then u:=low[u];
    124       end;
    125     end;
    126   end;
    127 
    128 function check:boolean;
    129   var i:longint;
    130   begin
    131     i:=p[ss];
    132     while i<>-1 do
    133     begin
    134       if (e[i].flow>0) and (e[i].po<>t) then exit(false);
    135       i:=e[i].next;
    136     end;
    137     exit(true);
    138   end;
    139 
    140 begin
    141   readln(te);
    142   while te>0 do
    143   begin
    144     dec(te);
    145     len:=0;
    146     fillchar(p,sizeof(p),255);
    147     fillchar(q,sizeof(q),0);
    148     readln(n,m,na,nb);
    149     for i:=1 to na do
    150       read(a[i]);
    151     for i:=1 to nb do
    152       read(b[i]);
    153     for i:=1 to m do
    154     begin
    155       readln(x,y);
    156       add(x,y);
    157     end;
    158     fillchar(v,sizeof(v),false);
    159     fillchar(f,sizeof(f),false);
    160     fillchar(c,sizeof(c),0);
    161     s:=0;
    162     for i:=1 to n do
    163       if not v[i] then
    164       begin
    165         h:=0;
    166         t:=0;
    167         tarjan(i);
    168       end;
    169     len:=-1;
    170     t:=2*s+1;
    171     ss:=2*s+2;
    172     tt:=2*s+3;
    173     for i:=1 to na do
    174     begin
    175       build(0,be[a[i]],inf);
    176       build(be[a[i]],0,0);
    177     end;
    178     for i:=1 to nb do
    179     begin
    180       build(be[b[i]]+s,t,inf);
    181       build(t,be[b[i]]+s,0);
    182     end;
    183     for i:=1 to n do
    184     begin
    185       j:=q[i];
    186       while j<>0 do
    187       begin
    188         y:=be[w[j].po];
    189         if y<>be[i] then
    190         begin
    191           build(be[i]+s,y,inf);
    192           build(y,be[i]+s,0);
    193         end;
    194         j:=w[j].next;
    195       end;
    196     end;
    197     for i:=1 to s do
    198     begin
    199       build(i,i+s,inf);
    200       build(i+s,i,0);
    201       build(ss,i+s,1);
    202       build(i+s,ss,0);
    203       build(i,tt,1);
    204       build(tt,i,0);
    205     end;
    206     sap(ss,tt);
    207     build(t,0,inf);
    208     build(0,t,0);
    209     sap(ss,tt);
    210     if check then writeln(e[len].flow)
    211     else writeln('no solution');
    212   end;
    213 end.
    View Code
  • 相关阅读:
    JavaScript过滤除连续的数字
    Intellij IDEA 配置Subversion插件
    匹配优先存在的问题,以及解决办法
    回溯
    Linux 启动流程
    tasklist、taskkill、taskmgr
    Mysql分区表
    Linux ${} 变量内容的提取和替换功能等
    Linux shell 提取文件名和目录名
    Mysql计划任务
  • 原文地址:https://www.cnblogs.com/phile/p/4473020.html
Copyright © 2011-2022 走看看