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 }



原文地址:https://www.cnblogs.com/acSzz/p/2715814.html