hdu 1507

来源:互联网 发布:阿里云服务器建站助手 编辑:程序博客网 时间:2024/06/05 18:27
题目大意:给你一个矩形,然后输入矩形里面池塘的坐标(不能放东西的地方),问可以放的地方中,最多可以放多少块1*2的长方形方块,并输出那些方块的位置。 这道题感觉出得很好,平时经常会遇到这些问题,但是不知道怎么解决。这个问题就是二分匹配,用匈牙利算法可以搞定,问题就是如何建图,相邻连着的就可以加一条边。这样建图后,最大匹配就是最大值。题目有指出 ( (N x M) - K <= 50), 所以最多也就 50 个点. 然后遍历图上每一个可行点点, 把它和他 上下左右的可行点连边, 最后就得到了一个二分图, 然后直接最大匹配, 不过结果有问题, 分析不透彻, 出现了重边. 再 分析下, 因为相邻块之间的下标和存在奇偶关系, 所以只取 偶数 或 奇数点 建图就行了.#include<stdio.h>#include<string.h>#define N 200struct node{int x,y;}link[N][N];int dir[5][3]={{0,1},{0,-1},{1,0},{-1,0}};int map[N][N],mark[N][N],n,m;int find(int x,int y){int a,b,i;for(i=0;i<4;i++){a=x+dir[i][0];b=y+dir[i][1];if(a>=1&&a<=n&&b>=1&&b<=m){if(!mark[a][b]&&!map[a][b]){mark[a][b]=1;if(link[a][b].x==0||find(link[a][b].x,link[a][b].y)){link[a][b].x=x;link[a][b].y=y;return 1;}}}}return 0;}int main(){int k,i,j,sum,a,b;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0)break;scanf("%d",&k);memset(map,0,sizeof(map));memset(link,0,sizeof(link));for(i=1;i<=k;i++){scanf("%d%d",&a,&b);map[a][b]=1;}sum=0;for(i=1;i<=n;i++)for(j=1;j<=m;j++){if(map[i][j]==0&&(i+j)%2==0)//关键{memset(mark,0,sizeof(mark));sum+=find(i,j);}}printf("%d\n",sum);for(i=1;i<=n;i++){for(j=1;j<=m;j++)if(link[i][j].x)  printf("(%d,%d)--(%d,%d)\n",i,j,link[i][j].x,link[i][j].y);}printf("\n");}return 0;}

0 0
原创粉丝点击