题目大意:
恩呃呃呃…给你A,B,C三类的物品,给出A,B;B,C的匹配关系,一个A,B,C类物品在一起就算一套物品。求出最多可以有多少套物品。
思路:
最大流的问题,建立一个超级源点和超级汇点,然后A-B-B’-C连边,从源点跑一次网络流然后就可以求出答案了
程序:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXN 1000010
#define MAX 999999999
using namespace std;
int n,m,k,s,t,c=2,ans=0;
int head[MAXN],next[MAXN],go[MAXN],w[MAXN],deep[MAXN];
inline int read(){
int date=0,w=1; char c=0;
while (c<'0'||c>'9'){if (c=='-') w=-1;c=getchar();}
while (c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
void add(int x,int y,int p){
go[c]=y; next[c]=head[x];
w[c]=p;
head[x]=c++;
go[c]=x; next[c]=head[y];
w[c]=0;
head[y]=c++;
}
bool bfs(){
int u,v;
queue<int>q;
memset(deep,0,sizeof(deep));
deep[s]=1;
q.push(s);
while (!q.empty()){
u=q.front();
q.pop();
for (int i=head[u];i;i=next[i]){
v=go[i];
if (w[i]&&!deep[v]){
deep[v]=deep[u]+1;
if (v==t) return true;
q.push(v);
}
}
}
return false;
}
int dfs(int x,int mi){
if (x==t) return mi;
int v,sum,cost=0;
for (int i=head[x];i;i=next[i]){
v=go[i];
if (w[i]&&deep[v]==deep[x]+1){
sum=dfs(v,min(mi-cost,w[i]));
if (sum>0){
w[i]-=sum;
w[i^1]+=sum;
cost+=sum;
if (cost==mi) break;
} else deep[v]=-1;
}
}
return cost;
}
int dinic(){
int ans=0;
while (bfs()) ans+=dfs(s,MAX);
return ans;
}
int main(){
int f,u,v;
n=read(); m=read(); k=read();
f=read();
for (int i=1;i<=f;i++){
u=read(); v=read();
add(v,u+m,1);
}
f=read();
for (int i=1;i<=f;i++){
u=read(); v=read();
add(u+n+m,v+n+n+m,1);
}
for (int i=1;i<=n;i++) add(i+m,i+m+n,1);
for (int i=1;i<=m;i++) add(n+m+k+n+1,i,1);
for (int i=1;i<=k;i++) add(i+n+n+m,n+n+m+k+2,1);
s=n+m+k+n+1; t=n+n+m+k+2;
printf("%d\n",dinic());
return 0;
}