题意用1*2的木板覆盖矩阵中的‘#’,(木板要覆盖的只能是‘#’),问最多能用几个木板覆盖
将#抽象为二分图的点,一个木板就是一个匹配,注意最后结果要除以2
Sample Input
1 6 ...... .##... .##... ....#. ....## ......
Sample Output
Case 1: 3
1 #include<stdio.h> 2 #include<string.h> 3 const int MAXN=1000; 4 char map[610][610]; 5 int tt[610][610]; 6 int uN,vN; //u,v数目 7 int g[MAXN][MAXN]; 8 int linker[MAXN]; 9 bool used[MAXN]; 10 bool dfs(int u) 11 { 12 int v; 13 for(v=0;v<vN;v++) 14 if(g[u][v]&&!used[v]) 15 { 16 used[v]=true; 17 if(linker[v]==-1||dfs(linker[v])) 18 { 19 linker[v]=u; 20 return true; 21 } 22 } 23 return false; 24 } 25 int hungary() 26 { 27 int res=0; 28 int u; 29 memset(linker,-1,sizeof(linker)); 30 for(u=0;u<uN;u++) 31 { 32 memset(used,0,sizeof(used)); 33 if(dfs(u)) res++; 34 } 35 return res; 36 } 37 38 int main() 39 { 40 int T; 41 int n; 42 scanf("%d",&T); 43 int iCase=0; 44 int tmp; 45 while(T--) 46 { 47 iCase++; 48 scanf("%d",&n); 49 50 tmp=0; 51 for(int i=0;i<n;i++) 52 { 53 scanf("%s",&map[i]); 54 for(int j=0;j<n;j++) 55 if(map[i][j]==‘#‘) tt[i][j]=tmp++; 56 } 57 memset(g,0,sizeof(g)); 58 uN=vN=tmp; 59 for(int i=0;i<n;i++) 60 for(int j=0;j<n;j++) 61 { 62 if(map[i][j]!=‘#‘) continue; 63 if(i>0&&map[i-1][j]==‘#‘) g[tt[i][j]][tt[i-1][j]]=1; 64 if(i<n-1&&map[i+1][j]==‘#‘) g[tt[i][j]][tt[i+1][j]]=1; 65 if(j>0&&map[i][j-1]==‘#‘) g[tt[i][j]][tt[i][j-1]]=1; 66 if(j<n-1&&map[i][j+1]==‘#‘) g[tt[i][j]][tt[i][j+1]]=1; 67 } 68 69 int res=hungary(); 70 printf("Case %d: %d\n",iCase,res/2); 71 } 72 return 0; 73 }
时间: 2024-10-13 17:57:52