poj2226Muddy Fields(二分图的最小点覆盖)

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

模板抄错,结果错了一下午。将连续横行上的*和连续纵桁上点分别看做两个点集,连接两集合中点的边就是图中的点。即求最小顶点覆盖最多的边。最小点覆盖=最大匹配。

有篇图片的讲解,挺好,很形象。http://ip96cns.blog.163.com/blog/static/170095192201117465473/

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int map[1000][1000];
 6 int r,c,link[1000],vis[1000];
 7 int find(int x,int n)//二分匹配模板
 8 {
 9     int i,j;
10     for(i = 1; i <= n ; i++)
11     {
12         if(map[x][i]&&!vis[i])
13         {
14             vis[i] = 1;
15             if(link[i]==0||find(link[i],n))
16             {
17                 link[i] = x;
18                 return 1;
19             }
20         }
21     }
22     return 0;
23 }
24 int main()
25 {
26     int i,j,k,a[100][100],b[100][100];
27     char s[100][100];
28     while(cin>>r>>c)
29     {
30         memset(link,0,sizeof(link));
31 
32         memset(map,0,sizeof(map));
33         k = 0;
34         int sum = 0;
35         int ii=1,jj=1;
36         for(i = 1 ; i <= r ; i++)
37         {
38             getchar();
39             for(j = 1; j <= c ; j++)
40             {
41                 scanf("%c", &s[i][j]);
42             }
43         }
44         for(i = 1; i <= r ; i++)
45         for(j = 1; j <= c ; j++)//建立X集合中的点
46         {
47             if(j==1&&i!=1&&s[i-1][c]=='*')
48             ii++;
49             if(s[i][j]=='*')
50             {
51                 a[i][j] = ii;
52             }
53             if(j!=c&&(s[i][j]=='*'&&s[i][j+1]!='*'))
54                 ii++;
55         }
56         for(i = 1; i <= c ; i++)//建立Y集合中的点
57         for(j = 1; j <= r ; j++)
58         {
59             if((j==1&&i!=1&&s[r][i-1]=='*'))
60             jj++;
61             if(s[j][i]=='*')
62             b[j][i] = jj;
63             if(j!=r&&(s[j][i]=='*'&&s[j+1][i]!='*'))
64             {
65                 jj++;
66             }
67         }
68         for(i = 1; i <= r ; i++)
69         for(j = 1; j <= c ; j++)//建立连接两集合点的边,即图中的"*"
70         {
71             if(s[i][j]=='*')
72             {
73                 map[a[i][j]][b[i][j]] = 1;
74             }
75         }
76         for(i = 1; i <= ii ; i++)
77         {
78             memset(vis,0,sizeof(vis));
79             if(find(i,jj))//寻找最大匹配
80             {
81                 sum++;
82             }
83         }
84         cout<<sum<<endl;
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/shangyu/p/2866673.html