简单的网络流问题,就是建图麻烦一些
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int N=500+10;
const int M=800+10; //都开大一点
const int INF=0x7f7f7f7f;
struct Edge
{
int to,nxt,cap,flow;
}edge[M];
int tot,first[N];
void addedge(int u,int v,int w,int rw=0)
{
edge[tot].to=v;edge[tot].cap=w;edge[tot].flow=0;
edge[tot].nxt=first[u];first[u]=tot++;
edge[tot].to=u;edge[tot].cap=rw;edge[tot].flow=0;
edge[tot].nxt=first[v];first[v]=tot++;
}
void init()
{
tot=0;
memset(first,-1,sizeof(first));
}
int gap[N],dep[N],cur[N],pre[N];
int sap(int s,int e,int n)
{
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,first,sizeof(first));
int u=s;
pre[u]=-1;
gap[0]=n;
int ans=0;
while(dep[s]<n)
{
if(u==e)
{
int Min=INF;
for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
if(edge[i].cap-edge[i].flow<Min)
Min=edge[i].cap-edge[i].flow;
for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
}
ans+=Min;
u=s;
continue;
}
bool flag=false;
int v;
for(int i=cur[u];i!=-1;i=edge[i].nxt)
{
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
{
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag)
{
u=v;
continue;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
int Min=n;
for(int i=first[u];i!=-1;i=edge[i].nxt)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
{
Min=dep[edge[i].to];
cur[u]=i;
}
dep[u]=Min+1;
gap[dep[u]]++;
if(u!=s) u=edge[pre[u]^1].to;
}
return ans;
}
int num[N];
int main()
{
int n,m,k;
string s,s0;
map<string,int> mm;
int cnt=1;
init();
memset(num,0,sizeof(num));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>s;
if(!mm[s]) mm[s]=cnt++;
num[mm[s]]++;
}
for(int i=1;i<cnt;i++)
addedge(0,i,num[i]);
scanf("%d",&m);
n=cnt-1;
int e=n+m+1;
for(int i=0;i<m;i++)
{
cin>>s;
cin>>s;
if(!mm[s]) //随时可能出现新的插座,要新加编号
{
mm[s]=m+1+cnt++;
}
addedge(mm[s],n+i+1,1);
addedge(n+i+1,e,1);
}
scanf("%d",&k);
for(int i=0;i<k;i++)
{
cin>>s0>>s;
if(!mm[s0])
{
mm[s0]=m+1+cnt++;
}
if(!mm[s])
{
mm[s]=m+1+cnt++;
}
addedge(mm[s],mm[s0],INF);
}
printf("%d\n",m-sap(0,e,m+1+cnt));
return 0;
}