POJ 2594 Treasure Exploration(可重点最小路径覆盖)

题目链接

解题思路

  裸题,先用floyd传递闭包,这样如果道路的中间点被用过了,两边的点依然可以相互匹配,即实现了重点的路径。

代码

const int maxn = 5e2+10;
const int maxm = 1e3+10;
int n, m, mp[maxn][maxn], match[maxn], vis[maxn];
void floyd() {
	for (int k = 1; k<=n; ++k)
		for (int i = 1; i<=n; ++i)
			for (int j = 1; j<=n; ++j)
				if (mp[i][k] && mp[k][j]) mp[i][j] = 1;
}
int find(int x) {
	for (int i = 1; i<=n; ++i) 
		if (mp[x][i] && !vis[i]) {
			vis[i] = 1;
			if (!match[i] || find(match[i])) {
				match[i] = x;
				return 1;
			}
		}
	return 0;
}
int main() {
	IOS;
	while(cin >> n >> m && (n||m)) {
		for (int i = 0, a, b; i<m; ++i) {
			cin >> a >> b; mp[a][b] = 1;
		}
		floyd();
		int ans = n;
		for (int i = 1; i<=n; ++i) {
			if (find(i)) --ans;
			zero(vis);
		}
		cout << ans << endl;
		zero(mp); zero(match);
	}
    return 0;
}
原文地址:https://www.cnblogs.com/shuitiangong/p/13532110.html