HDU 5652 India and China Origins
来源:互联网 发布:淘宝好评80字 编辑:程序博客网 时间:2024/06/06 21:03
题意:给你n*m的矩阵,0代表平原,1代表高山,接下来q年,每年在(x,y)的位置长出一座高山,问你第几年中国和印度不连通。
分析:第一种做法是BFS判断能不能从中国走到印度,如果一年一年找的话就会超时,所以查找第几年的时候,可以用二分查找,这样会快很多。
第二种做法是并查集,第0列的所有山都并起来,第m-1列的所有山都并起来,对于每座高山,把它周围8个方向的高山并起来,最后判断第0列和第m-1列的高山是不是在同一个集合里就行了。
BFS+二分:
# include <stdio.h># include <string.h> int n,m,map[505][505],vis[505][505],x[250005],y[250005]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; struct node { int x,y; }q[250005]; int Bfs() { int i,j,a,b,front=0,rear=0; memset(vis,0,sizeof(vis)); for(j=0;j<m;j++) if(map[0][j]==0) { q[rear].x=0; q[rear++].y=j; vis[0][j]=1; } while(front<rear) { for(i=0;i<4;i++) { a=q[front].x+dx[i]; b=q[front].y+dy[i]; if(a<0||a>=n||b<0||b>=m||map[a][b]==1||vis[a][b]==1) continue; if(a==n-1) return 1; q[rear].x=a; q[rear++].y=b; vis[a][b]=1; } front++; } return 0; } int Search(int l,int r) { int i,mid; for(i=r;i>(l+r)/2;i--) map[x[i]][y[i]]=0; while(l<r) { mid=(l+r)/2; if(Bfs()==1) { l=mid+1; for(i=l;i<=(l+r)/2;i++) map[x[i]][y[i]]=1; } else { r=mid; for(i=mid;i>(l+r)/2;i--) map[x[i]][y[i]]=0; } } return l; } int main() { int i,j,t,q; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) for(j=0;j<m;j++) scanf("%1d",&map[i][j]); scanf("%d",&q); for(i=1;i<=q;i++) scanf("%d%d",&x[i],&y[i]); if(Bfs()==0) { printf("0\n"); continue; } for(i=1;i<=q;i++) map[x[i]][y[i]]=1; if(Bfs()==1) { printf("-1\n"); continue; } printf("%d\n",Search(1,q)); } return 0; }
并查集:
# include <stdio.h> int n,m,map[505][505],root[505][505]; int Find(int i,int j) { if(root[i][j]!=i*m+j) root[i][j]=Find(root[i][j]/m,root[i][j]%m); return root[i][j]; } void Union(int i,int j,int a,int b) { int fx=Find(i,j),fy=Find(a,b); root[fx/m][fx%m]=fy; } void Search(int i,int j) { int k,l; if(j==0) Union(i,j,n,0); else if(j==m-1) Union(i,j,n,1); for(k=-1;k<=1;k++) for(l=-1;l<=1;l++) if(i+k>=0&&i+k<n&&j+l>=0&&j+l<m&&map[i+k][j+l]==1) Union(i,j,i+k,j+l); } void Init() { int i,j,k,l; for(i=0;i<n;i++) for(j=0;j<m;j++) root[i][j]=i*m+j; root[n][0]=n*m; root[n][1]=n*m+1; for(i=0;i<n;i++) for(j=0;j<m;j++) if(map[i][j]==1) Search(i,j); } int main() { int i,j,k,l,x,y,q,t,ans; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) for(j=0;j<m;j++) scanf("%1d",&map[i][j]); Init(); if(Find(n,0)==Find(n,1)) { printf("0\n"); continue; } scanf("%d",&q); for(i=1,ans=-1;i<=q;i++) { scanf("%d%d",&x,&y); if(ans!=-1) continue; Search(x,y); map[x][y]=1; if(Find(n,0)==Find(n,1)) ans=i; } printf("%d\n",ans); } return 0; }
0 0
- hdu 5652 India and China Origins(二分)
- hdu 5652 India and China Origins (★)
- hdu 5652 India and China Origins
- hdu 5652 India and China Origins
- HDU 5652 India and China Origins
- HDU 5652 India and China Origins
- HDU 5652 India and China Origins(并查集)
- [In Progress] HDU 5652 India and China Origins
- HDU-5652 India and China Origins(并查集)
- hdu 5652 India and China Origins (并查集)
- HDU 5652 India and China Origins 二分+搜索
- HDU-5652 India and China Origins(并查集)
- HDU 5652 India and China Origins(并查集)
- hdu 5652 India and China Origins 并查集
- hdu 5652 India and China Origins【二分+Bfs】
- hdu 5652 India and China Origins 并查集+BFS
- 7.4 D HDU 5652India and China Origins
- hdu5652 India and China Origins
- view 中函数的调用顺序,以xib自定义view为例
- 关于角色攻击范围判定和攻击判定
- Qt实现Ribbon效果
- 循环队列
- oc内存管理
- HDU 5652 India and China Origins
- <学习笔记>Windows驱动开发技术详解__Windows内存管理
- Ajax Loading —— spin.js
- mongoDB——shard简介
- Sping注入Date类型的3种方式
- 自言自语的第一篇博文
- IOS学习之——SDWebImage的使用
- html基础
- Android 使用Toolbar+DrawerLayout快速实现仿“知乎APP”侧滑导航效果