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 }

 

你可能感兴趣的:(poj)