这题能否用二分图做?
查看原帖
这题能否用二分图做?
409860
yu1102楼主2023/6/29 11:55

把设备看作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;
	}
}
2023/6/29 11:55
加载中...