poj 1422 Air Raid (最小路径覆盖 )

http://poj.org/problem?id=1422

题意:

一个地图上有n个小镇,以及连接着其中两个小镇的 有向边,而且这些边无法形成回路。现在选择一些小镇空降士兵(1个小镇最多1个士兵),士兵能沿着边走到尽头,问最少空降几个士兵,能遍历完所有的小镇。

题解:

一看这道题,求的是最少的路径覆盖住所有点。

二分图的最小路径覆盖,就是在图中 找一些路径,使其覆盖主所有的点,而且每个点只属于一条路径,

如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m;

 

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include< set>
 7 #include<map>
 8 #include<queue>
 9 #include<vector>
10 #include< string>
11  #define Min(a,b) a<b?a:b
12  #define Max(a,b) a>b?a:b
13  #define CL(a,num) memset(a,num,sizeof(a));
14  #define eps  1e-6
15  #define inf 10001000
16 
17  #define ll   __int64
18 
19  #define  read()  freopen("data.txt","r",stdin) ;
20  const  double pi  = acos(- 1.0);
21  const  int maxn =  200;
22 
23  using  namespace std;
24  int n,m;
25  int head[maxn] ;
26  int result[maxn],vis[maxn] ;
27  struct node
28 {
29      int v;
30      int next;
31 }p[maxn*maxn];
32  int cnt ;
33  void add( int u, int v)
34 {
35     p[cnt].v = v;
36     p[cnt].next = head[u];
37     head[u] = cnt++ ;
38 }
39  bool find( int u)
40 {
41 
42      for( int i = head[u];i!= - 1;i = p[i].next)
43     {
44          int v = p[i].v ;
45          if(!vis[v])
46         {
47             vis[v] =  1 ;
48              if(result[v] == - 1||find(result[v]))
49             {
50                 result[v] = u;
51                  return  true;
52             }
53         }
54     }
55      return  false ;
56 }
57  int  get()
58 {
59      int ans=  0;
60     CL(result,- 1);
61      for( int i =  1;i <= n;i++)
62     {
63         CL(vis, 0);
64          if(find(i))ans++;
65     }
66      return ans ;
67 }
68  int main()
69 {
70      // read() ;
71       int t ,i,x,y;
72     scanf( " %d ",&t);
73      while(t--)
74     {
75         cnt =  0;
76         CL(head,- 1) ;
77         scanf( " %d%d ",&n,&m);
78          for(i =  0 ; i < m;i++)
79         {
80             scanf( " %d%d ",&x,&y);
81             add(x,y);
82         }
83          int ans =  get() ;
84         printf( " %d\n ",n - ans) ;
85     }
86 }

 


 


你可能感兴趣的:(raid)