poj 2226

题意:一个由r行c列方格组成的田地,里面有若干个方格充满泥泞,其余方格都是草。要用长度不限,宽度为1的长木板来覆盖这些泥方格,但不能覆盖草地。最少要用多少个长木板?

分析:由于不能覆盖草地,这道题显得相当难。看别人的题解看了很久才明白它是如何跟二分匹配联系在一起的。这个建图实在是精妙。我们先把同一行每一段连续的泥方格作为一个顶点(其实就是一个长木板),这些顶点放进去集合x;而同一列每一段连续的泥方格也作为一个顶点,放进集合y。a∈x,b∈y,a,b若有相交则建一条边(a,b)。巧妙之处就在这条边,每条边所表示的就是原来的图中的一个泥方格,边与泥方格存在一一对应关系。若选了a(a∈x或a∈y)木板,则所有与a关联的边所表示的泥方格都会被覆盖。所以现在的问题就变成,求这个二分图的最小点覆盖数。由公式:最小点覆盖数=最大匹配数,即可知只要求最大匹配就OK。

另外,这道题坑爹之处是,图的大小不止50*50

View Code
 1 #include<cstdio>
 2 bool matrix[500][500],visited[500];
 3 char map[501][501];
 4 int r,c,mat[2][500],set[500][500],nx,ny;
 5 int path(int u)
 6 {
 7     int i;
 8     for(i=0;i<ny;i++)
 9     {
10         if(matrix[u][i] && !visited[i])
11         {
12             visited[i]=true;
13             if(mat[1][i]==-1 || path(mat[1][i]))
14             {
15                 mat[0][u]=i;
16                 mat[1][i]=u;
17                 return 1;
18             }
19         }
20     }
21     return 0;
22 }
23 int Hungary()
24 {
25     int ans=0,i,j;
26     for(i=0;i<nx;i++)
27         mat[0][i]=-1;
28     for(i=0;i<ny;i++)
29         mat[1][i]=-1;
30     for(i=0;i<nx;i++)
31     {
32         for(j=0;j<ny;j++)
33             visited[j]=false;
34         ans+=path(i);
35     }
36     return ans;
37 }
38 int main()
39 {
40     int i,j;
41     while(~scanf("%d%d%*c",&r,&c))
42     {
43         for(i=0;i<r;i++)
44         {
45             for(j=0;j<c;j++)
46                 matrix[i][j]=false;
47         }
48         for(i=0;i<r;i++)
49             gets(map[i]);
50         nx=0;
51         for(i=0;i<r;i++)
52         {
53             for(j=0;j<c;j++)
54             {
55                 if(map[i][j]=='*')
56                 {
57                     while(j<c && map[i][j]=='*')
58                         set[i][j++]=nx;
59                     nx++;
60                 }
61             }
62         }
63         ny=0;
64         for(j=0;j<c;j++)
65         {
66             for(i=0;i<r;i++)
67             {
68                 if(map[i][j]=='*')
69                 {
70                     while(i<r && map[i][j]=='*')
71                         matrix[set[i++][j]][ny]=true;
72                     ny++;
73                 }
74             }
75         }
76         printf("%d\n",Hungary());
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/ZShogg/p/2954740.html