题目链接: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 }