每一本书都要拆点,拆成入点和出点,因为每一本书只能匹配一次
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
int n, m, S, T;
namespace dinic{
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f;
int n, m, S, T;
int deep[M];
ll maxflow, edge[M];
int head[N], ver[M], nex[M], tot, cur[N];
inline void add(int x, int y, int z, bool o = 1)
{
ver[tot] = y;
edge[tot] = z;
nex[tot] = head[x];
head[x] = tot ++ ;
if(o)add(y, x, 0, 0);
}
bool bfs(){
queue<int>q;
memset(deep, 0x3f, sizeof deep);
deep[S] = 0;
cur[S] = head[S];
q.push(S);
while(q.size()){
int x = q.front();
q.pop();
for(int i = head[x]; ~i; i = nex[i]){
int y = ver[i], z = edge[i];
if(z > 0 && deep[y] == INF){
q.push(y);
deep[y] = deep[x] + 1;
cur[i] = head[i];
if(y == T)return true;
}
}
}
return false;
}
ll dfs(int x, ll flow)
{
if(x == T)return flow;
ll ans = 0, i, k;
for(i = cur[x] ;~i &&flow; i = nex[i]){
int y = ver[i];
ll z = edge[i];
if(z > 0 && deep[y] == deep[x] + 1){
k = dfs(y, min(flow, z));
if(k == 0)deep[y] = INF;
edge[i] -= k;
edge[i ^ 1] += k;
ans += k;
flow -= k;
}
}
return ans;
}
inline void main()
{
while(bfs()){
memcpy(cur, head, sizeof head);
maxflow += dfs(S, LINF);
}
}
inline void init(int _n, int _S, int _T)
{
n = _n, S = _S, T = _T;
memset(head, -1, sizeof head);
tot = 0, maxflow = 0;
}
}
int n1, n2, n3, m1, m2;
int main()
{
//1 ~ n1 : 书,入点
//n1 ~ 2 * n1 : 书,出点
//2 * n1 + 1 ~ 2 * n1 + n2 : 练习册,练习册连书的入点
//2 * n1 + n2 + 1 ~ 2 * n1 + n2 + n3 : 答案,书的出点连答案
scanf("%d%d%d", &n1, &n2, &n3);
S = 0, T = n1 + n2 + n3 + n1 + 1;
dinic::init(T * 10, S, T);
for(int i = 1; i <= n1; ++ i){
dinic::add(i, i + n1, 1);
}
scanf("%d", &m1);
for(int i = 1; i <= m1;++ i){
int x, y;
scanf("%d%d", &x, &y);
dinic::add(y + 2 * n1, x, 1);
}
scanf("%d", &m2);
for(int i = 1; i <= m2; ++ i){
int x, y;
scanf("%d%d", &x, &y);
dinic::add(x + n1, y + 2 * n1 + n2, 1);
}
for(int i = 1; i <= n2; ++ i){
dinic::add(S, 2 * n1 + i, 1);
}
for(int i = 1; i <= n3; ++ i){
dinic::add(2 * n1 + n2 + i, T, 1);
}
dinic::main();
printf("%lld\n", dinic::maxflow);
return 0;
}