hunnu OJ 11564 Easy Delete(二维坐标的离散化处理+最大匹配)
来源:互联网 发布:c语言二维数组例子 编辑:程序博客网 时间:2024/06/06 03:20
题意:•给出两类点坐标
–一类可删除
–一类不可删除
•选出最少的行或列,删除所有要删除的点。
思路:
•首先看到坐标范围很大,第一点要做的就是离散化。
•接着,将行看成二分图的X集合,将列看成二分图的Y集合,于是,我们要删除的点,就是X连接Y的一条边。
•最后,我们要求的就是最少的点覆盖所有的边。在二分图中,最大匹配==最小点覆盖。
需要注意的地方:
•判断每一个要删除的点,如果X方向和Y方向都有不能删除的点,就是Sorry。
•
•如果只有一个方向有,则必须使用另外一个方向删除该行/列的所有点。
•
剩下的点使用二分图最大匹配AC代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define clr(a,b) memset(a,b,sizeof(a))const int maxn = 1005;struct H{ int x,y,id,z;}no[maxn];bool cmp1(H a,H b){return a.x<b.x;}bool cmp2(H a,H b){return a.y<b.y;}int nx[maxn],ny[maxn],nz[maxn];int mp[maxn][maxn],mm[maxn][maxn];int vx[maxn],vy[maxn];int cx[maxn],cy[maxn];int vis[maxn],sign[maxn];int cnx,cny;int dfs(int x){ for(int i=0;i<cny;i++) { if(!vis[i]&&mp[x][i]) { vis[i]=1; if(sign[i] == -1||dfs(sign[i])) { sign[i]=x; return 1; } } } return 0;}int main(){#ifndef ONLINE_JUDGE freopen("E.txt","r",stdin); freopen("out.cpp","w",stdout);#endif // ONLINE_JUDGE int n; while(~scanf("%d",&n)) { for(int i=0;i<n;i++){ scanf("%d%d%d",&no[i].z,&no[i].x,&no[i].y); no[i].id=i; } sort(no,no+n,cmp1); cnx=-1; nx[no[0].id]=++cnx; for(int i=1;i<n;i++) { if(no[i].x==no[i-1].x) nx[no[i].id]=cnx; else nx[no[i].id]=++cnx; } sort(no,no+n,cmp2); cny=-1; ny[no[0].id]=++cny; for(int i=1;i<n;i++) { if(no[i].y==no[i-1].y) ny[no[i].id]=cny; else ny[no[i].id]=++cny; } cnx++; cny++; for(int i=0;i<n;i++) nz[no[i].id]=no[i].z; clr(mp,0);clr(vx,0);clr(vy,0); for(int i=0;i<n;i++) { if(nz[i]) mp[nx[i]][ny[i]]=1; else{ vx[nx[i]]=1;vy[ny[i]]=1; } } int flag=0; for(int i=0;i<cnx;i++){ if(vx[i]){ for(int j=0;j<cny;j++){ if(vy[j]) {if(mp[i][j]){flag=1;break;}} } } if(flag) break; } if(flag) {printf("Sorry\n");continue;} int ans=0; clr(cx,0);clr(cy,0); for(int i=0;i<cnx;i++){ if(vx[i]){ for(int j=0;j<cny;j++) if(mp[i][j]) {cy[j]=1;} } } for(int i=0;i<cny;i++){ if(vy[i]){ for(int j=0;j<cnx;j++) if(mp[j][i]) {cx[j]=1;} } } for(int i=0;i<cnx;i++){ if(cx[i]) {ans++;for(int j=0;j<cny;j++) if(mp[i][j])mp[i][j]=0;} } for(int i=0;i<cny;i++){ if(cy[i]) { ans++;for(int j=0;j<cnx;j++) if(mp[j][i])mp[j][i]=0; } } memset(sign,-1,sizeof(sign)); for(int i=0;i<cnx;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",ans); } return 0;}
0 0
- hunnu OJ 11564 Easy Delete(二维坐标的离散化处理+最大匹配)
- hunnu OJ 11567 Escaping(拆点型最大匹配/网络流)
- 坐标离散化处理
- HDU5925:Coconuts(二维坐标离散化 + DFS)
- 坐标的离散化
- 区域的个数(坐标离散化)
- 区域的个数 (坐标离散化)
- 区域的个数 (坐标离散化)
- 区域的个数(坐标离散化)
- 二维图像的离散傅立叶变换处理
- HDU4456————Crowd(离散化,坐标转化,二维树状数组)
- 南阳oj _600花儿朵朵(树状数组插线问点+坐标离散化)
- HNU 13103 Easy Delete 最小点覆盖=最大匹配数
- 离散化BFS,二维点的离散化
- NYOJ133子序列(坐标离散化)
- 坐标离散化技巧
- 坐标离散化
- 坐标离散化
- 如何取得系统时间
- 我的高效编程的秘诀--开发环境的重要性(IOS)
- H264语法分析之-slice
- NoSQL架构实践(二)——以NoSQL为主
- jquery库与prototype库冲突的解决方法
- hunnu OJ 11564 Easy Delete(二维坐标的离散化处理+最大匹配)
- CSplitterWnd的使用 .
- freamwork2实现单点登录,跨系统获取session信息
- hdu 1257 最少拦截系统 dp
- Spring boot 通用配置文件模板
- 自定义ActionBar
- C语言文件输入数组输出小代码
- HDU 5338 ZZX and Permutations
- Oracle,SQLServer的空值(null)判断及数值转换