POJ-1422 Air Raid 最小路径覆盖
题意:有N个十字路口,这些十字路口通过M条路连接,边是单向的,现在要派一些伞兵去空袭这些十字路口,每个伞兵可以沿着一条路空袭沿路的十字路口,问最少要派出多少伞兵。
解法:对于有向无环图求最小的路径覆盖数相当于将原图中的点拆开后,求一个最大匹配数,然后用顶点数减去最大匹配数就是最小路径覆盖了。
代码如下:
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int N, M; char G[125][125], vis[125]; int match[125]; bool path(int u) { for (int i = 1; i <= N; ++i) { if (!G[u][i] || vis[i]) continue; vis[i] = 1; if (!match[i] || path(match[i])) { match[i] = u; return true; } } return false; } int query() { int ret = 0; memset(match, 0, sizeof (match)); for (int i = 1; i <= N; ++i) { memset(vis, 0, sizeof (vis)); ret += path(i); } return N - ret; } int main() { int T, a, b; scanf("%d", &T); while (T--) { memset(G, 0, sizeof (G)); scanf("%d %d", &N, &M); for (int i = 0; i < M; ++i) { scanf("%d %d", &a, &b); G[a][b] = 1; } printf("%d\n", query()); } return 0; }
http://baike.baidu.com/view/2444809.htm 百度百科关于最小路径覆盖