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 }