HDU1507 Uncle Tom's Inherited Land*(二分匹配 匈牙利算法)
2016-03-13 22:32
393 查看
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1507
题意:给出一个n*m的地图,输入一个k,然后输入k个坐标,表示k个障碍物。问你一共能铺几个1*2的方格,然后输出方案。
思路:我一开始没考虑到什么,胡乱建图,一直WA,看到别人的建图觉得思路很好,所以写一下借鉴借鉴。把i+j是偶数的看做是二分匹配的X部分,是奇数的看做是二分匹配的Y部分。因为i+j是偶数的方块,它的上下左右都是i+j是奇数的,所以这样建图可行。然后就是二分匹配,输出方案的时候记录一下匹配的对象就可以了。
这题略坑,我开50个节点一直WA,也不RE,然后开了500节点就过了。
题意:给出一个n*m的地图,输入一个k,然后输入k个坐标,表示k个障碍物。问你一共能铺几个1*2的方格,然后输出方案。
思路:我一开始没考虑到什么,胡乱建图,一直WA,看到别人的建图觉得思路很好,所以写一下借鉴借鉴。把i+j是偶数的看做是二分匹配的X部分,是奇数的看做是二分匹配的Y部分。因为i+j是偶数的方块,它的上下左右都是i+j是奇数的,所以这样建图可行。然后就是二分匹配,输出方案的时候记录一下匹配的对象就可以了。
这题略坑,我开50个节点一直WA,也不RE,然后开了500节点就过了。
#include<cstdio> #include<cstring> #include<string> #include<iostream> #include<cstdlib> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #include<algorithm> using namespace std; const int INF=1e9+7; typedef pair<int,int> pii; #define PB push_back #define MP make_pair #define X first #define Y second map<int,pii> save; int n,m,idcnt,id[510][510],link[510]; int go[4][2]={{0,1},{1,0},{-1,0},{0,-1}}; bool G[550][550],vis[550]; inline bool judge(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;} bool dfs(int s){ for(int i=1;i<=idcnt;i++){ if(G[s][i]&&!vis[i]){ vis[i]=true; if(link[i]==-1||dfs(link[i])){ link[i]=s;return true; } } } return false; } int solve(){ memset(link,-1,sizeof link); int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if((i+j)&1)continue; memset(vis,false,sizeof vis); if(dfs(id[i][j]))ans++; } } return ans; } void print(){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++)if(id[i][j]!=-1){ int id1=id[i][j]; if(link[id1]==-1)continue; pii x=save[link[id1]]; printf("(%d,%d)--(%d,%d)\n",i,j,x.X,x.Y); } } printf("\n"); } void build(){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if((i+j)&1)continue; for(int k=0;k<4;k++){ int xx=i+go[k][0],yy=j+go[k][1]; if(judge(xx,yy)&&id[xx][yy]!=-1){ int id1=id[i][j],id2=id[xx][yy]; G[id1][id2]=true; } } } } } int main(){ // freopen("D://input.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ if(n==0&&m==0)break; save.clear(); memset(id,0,sizeof id); memset(G,false,sizeof G); int k;scanf("%d",&k); while(k--){ int a,b;scanf("%d%d",&a,&b); id[a][b]=-1; } idcnt=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++)if(id[i][j]!=-1){ id[i][j]=++idcnt; save[idcnt]=MP(i,j); } } build(); printf("%d\n",solve()); print(); } return 0; }
相关文章推荐
- Android系统之SD卡分析二
- Hello World (hadoop-eclipse插件安装与测试)
- 百度地图开发遇到错误:/baidumapsdk: Authentication Error errorcode: 230 uid: -1 appid -1 msg: APP Scode码校验失败
- Windows10中安装mysql5.7.11 社区版64位
- layer弹出层不居中解决方案
- 网络攻防工具介绍——Metasploit
- UVALive 7040 (容斥)
- Android基础知识
- Ubuntu 15.10安装Swift
- JAVA SE——反射
- Java 并发
- C++对象模型之详述C++对象的内存布局
- 使用Windows原生命令一键清空剪贴板
- HTML5中div、article、section的区别及使用介绍
- python中单元测试doctest | unittest
- 总结同学们第一周作业出现的问题
- 《Java程序设计》 第2周学习总结
- 20145316《Java程序设计》第二周学习总结
- 软件工程学习进度条
- PHP实现堆排序