网络流可以用来解决各种匹配问题,我们是知道的,比如二分匹配,这题事实上也是一个匹配问题,但是要注意……拆点!!为什么呢?因为满足题意的匹配中,书是只能匹配一份答案和练习册的,不拆点限流的话,一本书就可能会匹配多组,拆点如下e.g. :
剩下的就是模板了
上代码:
#include <bits/stdc++.h>
#define For(a,b,c,d) for(int a=b;a<=c;a+=d)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int nh2,cooh,R,m1,m2;
const int MAXN=100003;
const int MAXE=600003;
const int INF=0x3f3f3f3f;
int n,m,s,t,cnt,cur[MAXN],h[MAXN],num[MAXN];
int a[MAXN],fa[MAXN],Rflow[MAXN],d[MAXN],ans,q[MAXN],l;
bool f[MAXN];
typedef struct
{
int flow,cap,nxt,to;
}Edge;
Edge e[MAXE];
inline int read()
{
char ch;int x=0;int f=1;ch=getchar();
while (ch!='-'&&(ch<'0'||ch>'9'))
ch=getchar();
ch=='-'?f=-1:x=ch-'0',ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
inline void add_edge(int u,int v,int w)
{
e[cnt].flow=0;e[cnt].cap=w;e[cnt].to=v;e[cnt].nxt=h[u];h[u]=cnt++;
e[cnt].flow=0;e[cnt].cap=0;e[cnt].to=u;e[cnt].nxt=h[v];h[v]=cnt++;
}
bool bfs()
{
memset(d,-1,sizeof(d));
l=0;int u;
d[t]=0;q[l++]=t;
for (int i=0;i<l;i++)
{
u=q[i];
for (int j=h[u];~j;j=e[j].nxt)
{
int v=e[j].to;
if (e[j^1].cap>e[j^1].flow && d[v]==-1)
{
d[v]=d[u]+1;
q[l++]=v;
if(v==s)
return true;
}
}
}
return false;
}
int Maxflow()
{
int u=s;a[u]=0;Rflow[u]=1e9;
while(1)
{
ygg:
if (Rflow[u]&&u!=t)
{
if (!f[u])
f[u]=1;
else
cur[u]=e[cur[u]].nxt;
for (int& i=cur[u];~i;i=e[i].nxt)
{
int v=e[i].to;
if (e[i].cap>e[i].flow&&d[v]+1==d[u])
{
num[v]=i;a[v]=0;fa[v]=u;
Rflow[v]=min(Rflow[u],e[i].cap-e[i].flow);
u=v;f[v]=0;
goto ygg;
}
}
}
if (u==s)
return a[s];
if (u==t)
a[u]=Rflow[u];
if (Rflow[u]&&u!=t)
d[u]=-2;
e[num[u]].flow+=a[u];
e[num[u]^1].flow-=a[u];
a[fa[u]]+=a[u];
Rflow[fa[u]]-=a[u];
u=fa[u];
}
}
int main()
{
mem(h,-1);
nh2=read();R=read();cooh=read();
m1=read();
s=0;t=2*nh2+R+cooh+1;
For(i,1,m1,1)
{
int x,y;
x=read(),y=read();
add_edge(y,R+x,1);
}
m2=read();
For(i,1,m2,1)
{
int x,y;
x=read(),y=read();
add_edge(R+nh2+x,2*nh2+R+y,1);
}
For(i,1,R,1)
add_edge(s,i,1);
For(i,1,cooh,1)
add_edge(2*nh2+R+i,t,1);
For(i,1,nh2,1)
add_edge(R+i,R+nh2+i,1);
int ans=0;
while(bfs())
{
for (int i=0;i<=2*nh2+R+cooh+1;i++)
{
f[i]=0;
cur[i]=h[i];
}
ans+=Maxflow();
}
printf("%d\n",ans);
return 0;
}