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 }
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 }