思路:
最大流跑三分图匹配,注意每本书只能用一次,所以把每本书拆成两个点,连一条边。
不能直接用EdmondsKarp算法,也不能直接用不加优化的Dinic算法,这样会TLE7个点。 本题正解是Dinic算法加上当前弧优化。1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 inline int getint() { 8 char ch; 9 while(!isdigit(ch=getchar()));10 int x=ch^'0';11 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');12 return x;13 }14 const int inf=0x7fffffff;15 int s,t;16 struct Edge {17 int from,to;18 bool remain;19 };20 const int E=1400000,V=400002;21 Edge e[E];22 std::vector g[V];23 int sz=0;24 inline void add_edge(const int u,const int v,const bool w) {25 e[sz]=(Edge){u,v,w};26 g[u].push_back(sz);27 sz++;28 }29 int d[V];30 inline void SPFA() {31 d[s]=0;32 for(register int i=1;i<=t;i++) d[i]=inf;33 std::queue q;34 q.push(s);35 while(!q.empty()) {36 int x=q.front();37 q.pop();38 if(x==t) return;39 for(register unsigned i=0;i d[x])&&y.remain) {54 if(Augment(y.to,std::min(remain,y.remain))) {55 e[g[x][i]].remain^=true;56 e[g[x][i]^1].remain^=true;57 return true;58 }59 }60 }61 return false;62 }63 inline int Dinic() {64 int maxflow=0;65 for(SPFA();d[t]!=inf;SPFA()) {66 memset(cur,0,sizeof cur);67 while(Augment(s,true)) maxflow++;68 }69 return maxflow;70 }71 int main() {72 int n2=getint(),n1=getint(),n3=getint();73 s=0,t=n1+n2*2+n3+1;74 for(register int i=1;i<=n1;i++) {75 add_edge(s,i,true);76 add_edge(i,s,false);77 }78 for(register int m=getint();m;m--) {79 int a=getint(),b=getint();80 add_edge(b,n1+a,true);81 add_edge(n1+a,b,false);82 }83 for(register int i=1;i<=n2;i++) {84 add_edge(n1+i,n1+n2+i,true);85 add_edge(n1+n2+i,n1+i,false);86 }87 for(register int m=getint();m;m--) {88 int a=getint(),b=getint();89 add_edge(n1+n2+a,n1+n2*2+b,true);90 add_edge(n1+n2*2+b,n1+n2+a,false);91 }92 for(register int i=1;i<=n3;i++) {93 add_edge(n1+n2*2+i,t,true);94 add_edge(t,n1+n2*2+i,false);95 }96 printf("%d\n",Dinic());97 return 0;98 }