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