POJ 3041 简单二分图匹配

题意:

 

格子上知道一些固定点的位置
然后每一行,每一列都有一个枪,
行上的枪可以扫射一行
列上的枪可以扫射一列
问最少需要多少枪能覆盖格子上那些点

 

思路:

最小点覆盖=最大匹配

所以以x轴为一个点集 y轴为另一个点集建图

然后求最大匹配就好..

Tips:

nothing..

Code:

View Code
 1 #include <stdio.h>
 2 #include <cstring>
 3 #define clr(x) memset(x, 0, sizeof(x))
 4 const int INF = 0x1f1f1f1f;
 5 bool grid[510][510];
 6 
 7 struct Edge
 8 {
 9     int next;
10     int to;
11 }edge[1000000];
12 int tot;
13 int head[510];
14 
15 void add(int s, int u)
16 {
17     edge[tot].to = u;
18     edge[tot].next = head[s];
19     head[s] = tot++;
20 }
21 
22 int link[510];
23 int vis[510];
24 int n, sum;
25 
26 int dfs(int x)
27 {
28     for(int i = head[x]; i != -1; i = edge[i].next){
29         int y = edge[i].to;
30         if(!vis[y]){
31             vis[y] = true;
32             if(link[y] == 0 || dfs(link[y])){
33                 link[y] = x;
34                 return true;
35             }
36         }
37     }
38     return false;
39 }
40 
41 void solve()
42 {
43     clr(link);
44     sum = 0;
45     for(int i = 1; i <= n; ++i){
46         clr(vis);
47         if(dfs(i))
48             sum++;
49     }
50 }
51 
52 
53 int main()
54 {
55     int i, j, k;
56     int m, a, b;
57     while(scanf("%d %d", &n, &m) != EOF)
58     {
59         memset(head, -1, sizeof(head));
60         tot = 0;
61 
62         while(m--) {
63             scanf("%d %d", &a, &b);
64             add(a, b);
65         }
66         solve();
67         printf("%d\n", sum);
68     }
69     return 0;
70 }

 

 

posted @ 2012-09-14 12:07  Griselda.  阅读(148)  评论(0编辑  收藏  举报