poj 2226(最小点覆盖)

构图有点意思。。没想到。。

下面是构图:

把行里面连在一起的坑连起来视为一个点,即一块横木板,编上序号,Sample则转化为:

1 0 2 0
0 3 3 3
4 4 4 0
0 0 5 0

把这些序号加入X集合,再按列做一次则为:

1 0 4 0
0 3 4 5
2 3 4 0
0 0 4 0

 将 每一个 湿地的点 按其分配的行列 号  连边 ,如(i,j)为湿地 ,则用 其分配的  行  ——》 列,这样,我们求的就是 ,最小点覆盖。

View Code
  1 // File Name: 2226.cpp
  2 // Author: Missa
  3 // Created Time: 2013/2/10 星期日 23:58:51
  4 
  5 #include<iostream>
  6 #include<cstdio>
  7 #include<cstring>
  8 #include<algorithm>
  9 #include<cmath>
 10 #include<queue>
 11 #include<stack>
 12 #include<string>
 13 #include<vector>
 14 #include<cstdlib>
 15 #include<map>
 16 using namespace std;
 17 
 18 const int maxn = 55;
 19 int r,c;
 20 int mc[maxn][maxn];
 21 int mr[maxn][maxn];
 22 //***************匈牙利***********************
 23 int nx,ny;
 24 bool vis[maxn*maxn];
 25 int ma[maxn*maxn][maxn*maxn];
 26 int link[maxn*maxn];
 27 bool dfs(int x)
 28 {
 29     for(int y=1;y<=ny;y++)
 30     {
 31         if(!vis[y] && ma[x][y])
 32         {
 33             vis[y]=1;
 34             if(link[y]==-1 || dfs(link[y]))
 35             {
 36                 link[y]=x;
 37                 return true;
 38             }
 39         }
 40     }
 41     return false;
 42 }
 43 int maxmatch()
 44 {
 45     int ans=0;
 46     memset(link,-1,sizeof(link));
 47     for(int x=1;x<=nx;x++)
 48     {
 49         memset(vis,0,sizeof(vis));
 50         if(dfs(x)) ans++;
 51     }
 52     return ans;
 53 }
 54 //********************************************
 55 
 56 
 57 int main()
 58 {
 59     while(~scanf("%d%d",&r,&c))
 60     {
 61         char s[maxn];
 62         memset(mr,-1,sizeof(mr));
 63         memset(mc,-1,sizeof(mc));
 64         getchar();
 65         for(int i=1;i<=r;i++)
 66         {
 67             gets(s);
 68             for(int j=1;j<=c;j++)
 69             {
 70                 if(s[j-1]=='*')
 71                 {
 72                     mr[i][j]=0;
 73                     mc[i][j]=0;
 74                 }
 75             }
 76         }
 77         int numr=0,numc=0;
 78         for(int i=1;i<=r;i++)
 79         {
 80             for(int j=1;j<=c;j++)
 81             {
 82                 if(mr[i][j]==0)
 83                 {
 84                     numr++;
 85                     mr[i][j]=numr;
 86                     for(int k=j;k<=c;k++)
 87                     {
 88                         if(mr[i][k]==-1) break;
 89                         mr[i][k]=numr;
 90                     }
 91                 }
 92             }
 93         }
 94         for(int j=1;j<=c;j++)
 95         {
 96             for(int i=1;i<=r;i++)
 97             {
 98                 if(mc[i][j]==0)
 99                 {
100                     numc++;
101                     mc[i][j]=numc;
102                     for(int k=i;k<=r;k++)
103                     {
104                         if(mc[k][j]==-1)break;
105                         mc[k][j]=numc;
106                     }
107                 }
108             }
109         }
110         nx=numc,ny=numr;
111         memset(ma,0,sizeof(ma));
112         for(int i=1;i<=r;i++)
113             for(int j=1;j<=c;j++)
114                 if(mc[i][j] != -1)
115                     ma[mc[i][j]][mr[i][j]]=1;
116         printf("%d\n",maxmatch());
117     }
118     return 0;
119 }

 

posted @ 2013-02-11 00:28  Missa  阅读(149)  评论(0编辑  收藏  举报