建图:
把电器,插座,适配器这些都看作节点
构造一个超级源点和一个超级汇点
连接源点与电器,容量设为1
连接电器与插座,容量设为1
连接插座与汇点,容量设为1
连接适配器与插座,容量设为inf
在构造插座与适配器过程中,如果遇到一个没有出现过插座类型,就把这个插座作为一个新的节点加进去。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
#include<queue>
#include<math.h>
#include<cstdio>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=510;
const int inf=0xffffff;
int c[maxn][maxn];
int flow[maxn][maxn];
int dist[maxn];
bool vis[maxn];
int maxf[maxn];
int pre[maxn];
int maxflow(int s,int t,int n)
{
int f,v,u;
queue<int> q;
mem(flow,0);
f=0;
while(1)
{
q.push(s);
mem(vis,0);
mem(maxf,0);
vis[s]=1;
maxf[s]=inf;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
if(!vis[i] && c[u][i]-flow[u][i]>0)
{
vis[i]=1;
maxf[i]=min(maxf[u],c[u][i]-flow[u][i]);
q.push(i);
pre[i]=u;
}
}
}
f+=maxf[t];
if(maxf[t]==0) break;
for(int i=t;i!=s;i=pre[i])
{
flow[i][pre[i]] -= maxf[t];
flow[pre[i]][i] += maxf[t];
}
}
return f;
}
int main()
{
int n,mm,k;
int s,t;
while(~scanf("%d",&n))
{
int cnt=3;
map<string,int> m;
string str,str1;
s=1,t=2;
mem(c,0);
for(int i=1;i<=n;i++)
{
cin>>str;
m[str]=cnt;
c[cnt++][t]=1;
}
scanf("%d",&mm);
for(int i=0;i<mm;i++)
{
cin>>str>>str1;
m[str]=cnt;
c[s][cnt++]=1;
if(m.count(str1)==0)
m[str1]=cnt++;
c[m[str]][m[str1]]=1;
}
scanf("%d",&k);
for(int i=0;i<k;i++)
{
cin>>str>>str1;
if(m.count(str)==0)
m[str]=cnt++;
if(m.count(str1)==0)
m[str1]=cnt++;
c[m[str]][m[str1]]=inf;
}
printf("%d\n",mm-maxflow(s,t,cnt));
}
return 0;
}