rt
从第2个点开始就多流了一车子
求debug
//testbook in the middle
//exercises with the start point
//and answers with the end point
//dinic 好像在n分图上优秀一点
#include <bits/stdc++.h>
using namespace std;
int n1,n2,n3;
int m1,m2;
int s,t;
struct Node
{
int st;
int cur;
int dep;
}node[50000];//统一开node好写一点
int cnt=1;
struct Edge
{
int des;
int next;
int lim;
}edge[203000];
int gap[100000];
int maxn;
inline void Add_edge(int u,int v,int w)
{
cnt++;
edge[cnt].lim=w;
edge[cnt].des=v;
edge[cnt].next=node[u].st;
node[u].st=cnt;
return;
}
inline void Input()
{
freopen("data.in","r",stdin);
scanf("%d%d%d",&n1,&n2,&n3);
scanf("%d",&m1);
for(int i=1;i<=m1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
Add_edge(u,v+n1,0);
Add_edge(v+n1,u,1);
}
scanf("%d",&m2);
for(int i=1;i<=m2;i++)
{
int u,v;
scanf("%d%d",&u,&v);
Add_edge(u,v+n1+n2,1);
Add_edge(v+n1+n2,u,0);
}
s=n1+n2+n3+1;
t=s+1;
for(int i=1;i<=n2;i++)
{
Add_edge(s,n1+i,1);
Add_edge(n1+i,s,0);
}
for(int i=1;i<=n3;i++)
{
Add_edge(t,n1+n2+i,0);
Add_edge(n1+n2+i,t,1);
}
return;
}
void bfs()
{
queue<int> heap;
heap.push(t);
node[t].dep=1;
gap[1]++;
while(!heap.empty())
{
int poi=heap.front();
heap.pop();
for(int i=node[poi].st;i!=0;i=edge[i].next)
{
int flag=edge[i].des;
if(!node[flag].dep)
{
node[flag].dep=node[poi].dep+1;
gap[node[flag].dep]++;
heap.push(flag);
}
}
}
return;
}
int dfs(int poi,int flow)
{
if(poi==t)
{
maxn+=flow;
return flow;
}
int used=0;
int rlow=0;
for(int i=node[poi].cur;i!=0;i=edge[i].next)
{
node[poi].cur=i;
int flag=edge[i].des;
if(edge[i].lim&&node[flag].dep+1==node[poi].dep)
{
rlow=dfs(flag,min(flow-used,edge[i].lim));
if(rlow)
{
used+=rlow;
edge[i].lim-=rlow;
edge[i^1].lim+=rlow;
}
if(used==flow)return used;
}
}
--gap[node[poi].dep];
if(gap[node[poi].dep]==0)
{
node[s].dep=t+1;
}
node[poi].dep++;
gap[node[poi].dep]++;
return used;
}
int ISAP()
{
bfs();
while(node[s].dep<=t)
{
for(int i=1;i<=t;i++)
{
node[i].cur=node[i].st;
}
dfs(s,INT_MAX);
}
return maxn;
}
int main()
{
Input();
printf("%d\n",ISAP());
return 0;
}
/*
5 3 4
5
4 3
2 2
5 2
5 1
5 3
5
1 3
3 1
2 2
3 3
4 3
*/