有起点终点的限制的路径覆盖
首先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

 

posted on 2015-01-26 18:04  acphile  阅读(187)  评论(0编辑  收藏  举报