把设备看作X,插座看作Y,如果设备u可以通过若干个转换器接上v,则连边u->v。答案为设备总数减去最大匹配。
按照这个方法写,结果WA。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100 + 10, MAX_STYLE = MAXN * 4;
int n, m, match[MAXN];
bool G[MAX_STYLE][MAX_STYLE], vis[MAXN];
string a[MAXN], b[MAXN];
string name;
map<string, int> id;
bool dfs(int u)
{
if (vis[u]) return 0;
vis[u] = 1;
for (int v = 1; v <= m; v++) if (a[u] == b[v] || G[id[a[u]]][id[b[v]]])
{
if (!match[v] || dfs(match[v]))
{
match[v] = u;
return 1;
}
}
return 0;
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
int T, kase = 0;
cin >> T;
while (T--)
{
if (kase++) puts("");
int cnt = 0;
id.clear();
cin >> m;
for (int i = 1; i <= m; i++)
{
cin >> b[i];
if (!id.count(b[i])) id[b[i]] = ++cnt;
}
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> name >> a[i];
if (!id.count(a[i])) id[a[i]] = ++cnt;
}
memset(G, 0, sizeof(G));
int turn;
cin >> turn;
while (turn--)
{
string s1, s2;
cin >> s1 >> s2;
G[id[s1]][id[s2]] = 1;
}
for (int k = 1; k <= cnt; k++)
for (int i = 1; i <= cnt; i++)
for (int j = 1; j <= cnt; j++)
G[i][j] |= (G[i][k] & G[k][j]);
memset(match, 0, sizeof(match));
int ans = n;
for (int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
ans -= dfs(i);
}
cout << ans << endl;
}
}