HDU 1151 Air Raid(最小路径覆盖)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151

题目大意:在一个城镇,有m个路口,和n条路,这些路都是单向的,而且路不会形成环,现在要弄一些伞兵去巡查这个城镇, 

伞兵只能沿着路的方向走,问最少需要多少伞兵才能把所有的路口搜一遍。

解题思路:这个题目就转换成求解有向无环图的最小路径覆盖问题了。 

一个结论:有向无环图的最小路径覆盖=该图的顶点数-该图的最大匹配。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 const int N=205;
 8 
 9 int n,m;
10 int link[N];
11 bool vis[N];
12 vector<int>v[N];
13 
14 bool dfs(int u){
15     for(int i=0;i<v[u].size();i++){
16         int t=v[u][i];
17         if(!vis[t]){
18             vis[t]=true;
19             if(link[t]==-1||dfs(link[t])){
20                 link[t]=u;
21                 return true;
22             }
23         }
24     }
25     return false;
26 }
27 
28 int max_match(){
29     memset(link,-1,sizeof(link));
30     int ans=0;
31     for(int i=1;i<=n;i++){
32         memset(vis,false,sizeof(vis));
33         if(dfs(i)) ans++;
34     }
35     return ans;
36 }
37 
38 int main(){
39     int t;
40     while(~scanf("%d",&t)){
41         while(t--){
42             scanf("%d%d",&n,&m);
43             for(int i=0;i<=n;i++) v[i].clear();
44             for(int i=1;i<=m;i++){
45                 int a,b;
46                 scanf("%d%d",&a,&b);
47                 v[a].push_back(b);
48             }
49             //有向无环图的最小路径覆盖=该图的顶点数-该图的最大匹配。
50             printf("%d
",n-max_match());
51         }
52     }
53     return 0;
54 }
原文地址:https://www.cnblogs.com/fu3638/p/8785111.html