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;
}