POJ 1548 Robots(最小路径覆盖)
解题思路
题目要求用少的机器人访问所有的点,也是说找最少的路径访问所有的点,也就是最小路径覆盖问题。
题目的关键是如何建图,因为机器人只能向下走或者向右走,那么就在当前的垃圾点所在的行往下,每一列出现的第一个垃圾点之间建一条边即可。
代码
const int maxn = 25;
const int maxm = 25*25;
int g[maxn][maxn], nums, mp[maxm][maxm];
int a, b, vis[maxm], match[maxm];
void solve(int x, int y) {
for (int i = x; i<maxn; ++i)
for (int j = y; j<maxn; ++j)
if (g[i][j] && g[i][j]!=g[x][y]) {
mp[g[x][y]][g[i][j]] = 1; break;
}
}
int find(int x) {
for (int i = 1; i<=nums; ++i)
if (mp[x][i] && !vis[i]) {
vis[i] = true;
if (!match[i] || find(match[i])) {
match[i] = x;
return 1;
}
}
return 0;
}
int main() {
while(cin >> a >> b && (~a||~b)) {
if (!a && !b) {
cout << 0 << endl;
continue;
}
g[a][b] = ++nums;
while(cin >> a >> b && (a||b)) g[a][b] = ++nums;
for (int i = 1; i<maxn; ++i)
for (int j = 1; j<maxn; ++j)
if (g[i][j]) solve(i, j);
int ans = nums;
for (int i = 1; i<=nums; ++i) {
if (find(i)) --ans;
zero(vis);
}
cout << ans << endl;
nums = 0; zero(g); zero(mp); zero(match);
}
return 0;
}