标签:flag 并且 fine pac nmap 区域 效率 否则 向量
最大匹配问题
题意:题目意思:
给定一个 n * m 的矩阵格子, 第二行给定一个k值表示池塘,接下来给出池塘坐标,要求的就是在不是池塘的区域用1 * 2 的小矩形填充它 ,问 最多能填充几个小矩形,并且打印出所有矩阵!
这题拿到手毫无头绪 是这个专题最难的一题了
这题值得多打几遍
#include<bits/stdc++.h> using namespace std; #define N 105 int mp[N][N]; int used[N]; int vis[N]; int n,m,r,c; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; int flag[N][N]; int ans[N][2]; int cnt; vector<int>g[N*N]; bool dfs(int x) { for(int j=0;j<g[x].size();j++) { if(!used[ g[x][j] ]) //所有的j都改为了g[x][j] { used[ g[x][j] ]=1; if(!vis[ g[x][j] ]||dfs(vis[ g[x][j] ])) { vis[ g[x][j] ]=x; return true; } } } return false; } int find1(void) { int ans=0; memset(vis,0,sizeof(vis)); for(int i=1;i<=cnt-1;i++) { memset(used,0,sizeof(used)); if(dfs(i))ans++; } return ans; } bool inmap(int x,int y) { if(x>=1&&x<=n&&y>=1&&y<=m)return true; else return false; } int main() { while(scanf("%d%d",&n,&m),n||m) { memset(mp,0,sizeof(mp)); memset(flag,0,sizeof(flag)); memset(ans,0,sizeof(ans)); for(int i=0;i<=N*N;i++)g[i].clear(); int q; scanf("%d",&q); while(q--) { int a,b; scanf("%d%d",&a,&b); mp[a][b]=1; } cnt=1; for(int i=1;i<=n;i++)//扫描各个点 进行离散化 for(int j=1;j<=m;j++) if(mp[i][j]==0) { ans[cnt][0]=i; ans[cnt][1]=j;//这个数组用的巧妙!! flag[i][j]=cnt++;//从小到大标记各个有效点 } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(flag[i][j]) if( 1&(i+j) )//只处理奇数的 可以提高效率 否则的话 ans为两倍(匹配两次) 并且打印各个点就会出错!!很重要 { for(int k=0;k<4;k++)//类似dfs 扫描一个点 将其匹配的点(就是相邻点)存入匹配向量!!! { int x=i+dx[k]; int y=j+dy[k]; if(inmap(x,y)&&flag[x][y]) g[ flag[i][j] ].push_back( flag[x][y] ); } } printf("%d\n",find1()); for(int i=1;i<cnt;i++)//使用vis数组来打印 !这时用上了之前所处理的记录数组 if(vis[i]) { printf("(%d,%d)--(%d,%d)\n", ans[i][0],ans[i][1],ans[ vis[i] ][0],ans[ vis[i] ][1] ); } printf("\n"); } }
标签:flag 并且 fine pac nmap 区域 效率 否则 向量
原文地址:https://www.cnblogs.com/bxd123/p/10372433.html