标签:
题意:N*M的矩形,向其中填充1*2的小块矩形,黑色的部分不能填充,问最多可以填充多少块。
链接:点我
黑白棋最大匹配
将棋盘中i+j为奇数的做A集合,偶数的做B集合,相邻的则建立联系。于是便转换成寻找最大匹配的问题
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN=510; 16 int a[110][110]; 17 int b[100]; 18 int n,m,tt; 19 /* *********************************************************** 20 //二分图匹配(匈牙利算法的DFS实现)(邻接矩阵形式) 21 //初始化:g[][]两边顶点的划分情况 22 //建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配 23 //g没有边相连则初始化为0 24 //uN是匹配左边的顶点数,vN是匹配右边的顶点数 25 //调用:res=hungary();输出最大匹配数 26 //优点:适用于稠密图,DFS找增广路,实现简洁易于理解 27 //时间复杂度:O(VE) 28 //************************************************************ */ 29 //顶点编号从0开始的 30 int uN,vN;//u,v的数目,使用前面必须赋值 31 int g[MAXN][MAXN];//邻接矩阵 32 int linker[MAXN]; 33 bool used[MAXN]; 34 bool dfs(int u) 35 { 36 for(int v = 0; v < vN;v++) 37 if(g[u][v] && !used[v]) 38 { 39 used[v] = true; 40 if(linker[v] == -1 || dfs(linker[v])) 41 { 42 linker[v] = u; 43 return true; 44 } 45 } 46 return false; 47 } 48 int hungary() 49 { 50 int res = 0; 51 memset(linker,-1,sizeof(linker)); 52 for(int u = 0;u < uN;u++) 53 { 54 memset(used,false,sizeof(used)); 55 if(dfs(u))res++; 56 } 57 return res; 58 } 59 int main() 60 { 61 int i,j,k; 62 #ifndef ONLINE_JUDGE 63 freopen("1.in","r",stdin); 64 #endif 65 while(scanf("%d%d",&n,&m)!=EOF) 66 { 67 if(n==0&&m==0) break; 68 scanf("%d",&k); 69 int u,v; 70 cl(a); 71 while(k--) 72 { 73 scanf("%d%d",&u,&v); 74 u--,v--; 75 a[u][v]=-1; 76 } 77 int tot=0; 78 for(i=0;i<n;i++) 79 { 80 for(j=0;j<m;j++) 81 { 82 if(a[i][j]!=-1) 83 { 84 b[tot]=i*m+j; 85 a[i][j]=tot++; 86 } 87 } 88 } 89 cl(g); 90 for(i=0;i<n;i++) 91 { 92 for(j=0;j<m;j++) 93 { 94 if(a[i][j]!=-1&&((i+j)%2==1)) 95 { 96 int w=a[i][j]; 97 if(i>0&&a[i-1][j]!=-1) 98 g[w][a[i-1][j]]=1; 99 if(i<n-1&&a[i+1][j]!=-1) 100 g[w][a[i+1][j]]=1; 101 if(j>0&&a[i][j-1]!=-1) 102 g[w][a[i][j-1]]=1; 103 if(j<m-1&&a[i][j+1]!=-1) 104 g[w][a[i][j+1]]=1; 105 } 106 } 107 } 108 vN=uN=tot; 109 printf("%d\n",hungary()); 110 for(i=0;i<tot;i++) 111 { 112 if(linker[i]!=-1) 113 { 114 int x1=b[i]/m; 115 int y1=b[i]%m; 116 int x2=b[linker[i]]/m; 117 int y2=b[linker[i]]%m; 118 printf("(%d,%d)--(%d,%d)\n",x1+1,y1+1,x2+1,y2+1); 119 } 120 } 121 printf("\n"); 122 } 123 }
标签:
原文地址:http://www.cnblogs.com/cnblogs321114287/p/4618037.html