用map<string, int>为每一个插座,插头,设备指定一个编号u,先把源点与所有设备,设备与对应的插头,插座与汇点连起来,这些弧的容量为1,然后把转化器加进来,转化器相连的两个东西间加弧,容量为inf,然后用ek模板求最大流。
我的源点设为了0,汇点设为了500,(汇点要设大一些,否则可能会与插座插头等的编号重复),inf为0x3f3f3f3f。
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
typedef struct Edge{
int from, to, cap, flow;
Edge(int a=0, int b=0, int c=0, int d=0):from(a), to(b), cap(c), flow(d){}
}Edge;
vector<Edge> edge;
vector<int> G[550];
map<string, int> mp;
int ncz, nct, nzh;
int a[100000];
int p[100000];
void init()
{
for(int i = 0; i < 501; i++)
G[i].clear();
edge.clear();
}
int ek()
{
int flow = 0;
for(;;)
{
memset(a, 0, sizeof(a));
queue<int> que;
que.push(0);
a[0] = inf;
while(!que.empty())
{
int x = que.front();
que.pop();
for(int i = 0; i < G[x].size(); i++)
{
Edge& e = edge[G[x][i]];
if(!a[e.to] && e.cap>e.flow)
{
p[e.to] = G[x][i];
a[e.to] = min(a[x], e.cap-e.flow);
que.push(e.to);
}
}
if(a[500]) break;
}
if(!a[500]) break;
for(int u = 500; u != 0; u = edge[p[u]].from)
{
edge[p[u]].flow += a[500];
edge[p[u]^1].flow -= a[500];
}
flow += a[500];
}
return flow;
}
int main()
{
//freopen("ztest.txt","r",stdin);
//freopen("zans.txt","w",stdout);
int tt;
scanf("%d", &tt);
while(tt--)
{
mp.clear();
init();
scanf("%d", &ncz);
int m;
int u = 1;
for(int i = 0; i < ncz; i++)
{
string temp;
int t;
cin >> temp;
if(!mp.count(temp))
mp[temp] = u++;
t = mp[temp];
//printf("%d %c\n",temp,temp);
edge.push_back(Edge(t, 500, 1, 0));
edge.push_back(Edge(500, t, 0, 0));
m = edge.size();
G[t].push_back(m-2);
G[500].push_back(m-1);
}
scanf("%d", &nct);
for(int i = 0; i < nct; i++)
{
string str1;
string str2;
int t1;
int t2;
cin >> str1 >> str2;
if(!mp.count(str1)) mp[str1] = u++;
if(!mp.count(str2)) mp[str2] = u++;
t1 = mp[str1];
t2 = mp[str2];
edge.push_back(Edge(0, t1, 1, 0));
edge.push_back(Edge(t1, 0, 0, 0));
edge.push_back(Edge(t1, t2, 1, 0));
edge.push_back(Edge(t2, t1, 0, 0));
m = edge.size();
G[0].push_back(m-4);
G[t1].push_back(m-3);
G[t1].push_back(m-2);
G[t2].push_back(m-1);
}
scanf("%d", &nzh);
for(int i = 0; i < nzh; i++)
{
string str1;
string str2;
int t1;
int t2;
cin >> str1 >> str2;
if(!mp.count(str1)) mp[str1] = u++;
if(!mp.count(str2)) mp[str2] = u++;
t1 = mp[str1];
t2 = mp[str2];
edge.push_back(Edge(t1,t2, inf, 0));
edge.push_back(Edge(t2, t1, 0, 0));
m = edge.size();
G[t1].push_back(m-2);
G[t2].push_back(m-1);
}
printf("%d\n", nct-ek());
if(tt)
printf("\n");
}
return 0;
}