Maximum flow.
A stream can correspond to a distribution method.
It is clear that the maximum flow can represent the maximum number of matches
#include <cstdio>#include<algorithm>#include<cstring>using namespacestd;Const intMAXN = -+Ten;Const intMAXM =100000+Ten;Const intMAXL = -;Const intINF =0x3f3f3f3f;CharS[MAXN][MAXL],T[MAXL],T2[MAXL];intG[maxn],v[maxm],nex[maxm],f[maxm],eid;intId[maxn],vid;ints,t;intD[MAXN],GAP[MAXN];intn,m,k,a1,a2;voidAddedge (intAintBintF) {V[eid]=b; F[eid]=f; Nex[eid]=g[a]; g[a]=eid++; V[eid]=a; f[eid]=0; NEX[EID]=G[B]; g[b]=eid++;}voidbuild () {memset (g,-1,sizeof(g)); Eid=0; Vid=0; S=++vid; t=++vid; scanf ("%d",&N); for(intI=1; i<=n;i++) {scanf ("%s", S[i]); Id[i]=0; for(intj=1; j<i;j++)if(strcmp (s[i],s[j]) = =0) {Id[i]=Id[j]; Break; } if(!id[i]) id[i]=++vid; Addedge (Id[i],t,1); //printf ("id[%d]=%d\n", I,id[i]);} scanf ("%d",&m); for(inti=n+1; i<=n+m;i++) {scanf ("%s", T); scanf ("%s", S[i]); Id[i]=0; for(intj=1; j<i;j++)if(strcmp (s[i],s[j]) = =0) {Id[i]=Id[j]; Break; } if(!id[i]) id[i]=++vid; Addedge (S,id[i],1); //printf ("id[%d]=%d\n", I,id[i]);} scanf ("%d",&k); for(intI=1; i<=k;i++) {scanf ("%s", T); scanf ("%s", T2); for(intj=1; j<=n+m;j++)if(strcmp (s[j],t) = =0) {A1=id[j]; Break;} for(intj=1; j<=n+m;j++)if(strcmp (s[j],t2) = =0) {A2=id[j]; Break;} Addedge (A1,a2,inf); //printf ("%d%d\n", A1,A2); }}intISAP (intUintflow) { if(u==t)returnflow; intCur=0, aug,mindist=vid; for(intI=g[u];~i;i=Nex[i])if(F[i] && d[v[i]]+1==D[u]) { the=isap (V[i],min (flow-cur,f[i])); Cur+=; F[i]-=; F[i^1]+=; if(Cur==flow | | d[s]>=vid) {returncur; } } if(cur==0) { if(!--Gap[d[u]]) {D[s]=vid; returncur; } for(intI=g[u];~i;i=nex[i])if(F[i]) mindist=min (d[v[i]],mindist); ++gap[d[u]=mindist+1]; } returncur;}voidsolve () {memset (d,0,sizeof(d)); Memset (Gap,0,sizeof(GAP)); intres=0; gap[0]=vid; while(d[s]<vid) {res+=ISAP (S,inf); } printf ("%d\n", M-res);}intMain () {intT; scanf ("%d",&T); while(t--) {build (); Solve (); if(T) printf ("\ n"); } return 0;}
uva753 A Plug for UNIX