HDU 5652 India and China Origins
2016-04-02 12:21
465 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652
中文题面:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=681&pid=1002
题意:两个国家之间有一个地图,地图上有一些山峰,即障碍。一开始两个国家是相通的,现在在地图上依次出现Q座山峰,一年出现一座。问两国最早不联通是在几年后。
思路:可以用并查集来做,地图上有n*m个点,那么两个国家的编号可以设为0和m*n+1,将地图上的每个点都与四个方向判一下是否可行,就合并。上下两行边界分别去和0和n*m+1合并。将所有的操作倒着处理,假设一开始Q座山峰都是出现的,然后每次减少一座山峰,就把这个位置和地图上联通起来,判断0和n*m+1这两个点的连通性。
中文题面:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=681&pid=1002
题意:两个国家之间有一个地图,地图上有一些山峰,即障碍。一开始两个国家是相通的,现在在地图上依次出现Q座山峰,一年出现一座。问两国最早不联通是在几年后。
思路:可以用并查集来做,地图上有n*m个点,那么两个国家的编号可以设为0和m*n+1,将地图上的每个点都与四个方向判一下是否可行,就合并。上下两行边界分别去和0和n*m+1合并。将所有的操作倒着处理,假设一开始Q座山峰都是出现的,然后每次减少一座山峰,就把这个位置和地图上联通起来,判断0和n*m+1这两个点的连通性。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <iostream> #include <algorithm> #include <stack> #include <map> #include <set> #include <vector> #include <sstream> #include <queue> #include <utility> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;i++) #define Rrep(i,j,k) for (int i=j;i>=k;i--) #define Clean(x,y) memset(x,y,sizeof(x)) #define LL long long #define ULL unsigned long long #define inf 0x7fffffff #define mod %100000007 const int dx[4] = {0,0,1,-1}; const int dy[4] = {1,-1,0,0}; const int maxn = 500; int T,n,m; char a[maxn+10][maxn+10]; int father[maxn*maxn+10]; int qx[maxn*maxn+10],qy[maxn*maxn+10]; int Q; int getpos(int x,int y) { return (x-1)*m + y; } int getfather(int x) { if ( father[x] == x ) return x; return father[x] = getfather( father[x] ); } void unio(int x,int y) { int fa = getfather(x); int fb = getfather(y); if ( fa != fb ) { father[fa] = fb; } } void init() { rep(i,0,m*n+1) father[i] = i; rep(i,1,n) { getchar(); rep(j,1,m) a[i][j] = getchar(); } scanf("%d",&Q); rep(i,1,Q) { scanf("%d%d",&qx[i],&qy[i]); qx[i]++; qy[i]++; a[qx[i]][qy[i]] = '1'; //先将所有的山峰都放上 } rep(i,1,m) { if ( a[1][i] ) unio( getpos(1,i) , 0 ); //上下边界两行和国家联通 if ( a [i] ) unio( getpos(n,i) , n*m+1 ); } int tx,ty; rep(i,1,n) //将整个地图可行的地方都联通 rep(j,1,m) if ( a[i][j] == '0' ) rep(k,0,3) { tx = i + dx[k]; ty = j + dy[k]; if ( tx >=1 && tx <= n && ty>=1 && ty <= m && a[tx][ty] == '0' ) unio( getpos(i,j) , getpos(tx,ty) ); } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); int st = 0; int ed = n*m + 1; if ( getfather(st) == getfather(ed) ) //一开始就是连通的 { puts("-1"); continue; } int tx,ty; Rrep(i,Q,1) { a[ qx[i] ][ qy[i] ] = '0';//每次去掉一个山峰,再判断图的连通性 rep(k,0,3) { tx = qx[i] + dx[k]; ty = qy[i] + dy[k]; if ( tx >=1 && tx <= n && ty>=1 && ty <= m && a[tx][ty] == '0' ) unio( getpos(qx[i],qy[i]) , getpos(tx,ty) ); } if ( getfather(st) == getfather(ed) ) { printf("%d\n",i); break; } } } return 0; }
相关文章推荐
- json和xml比较与区别
- 静态变量static学习
- 线性回归-3-最小二乘法
- 顺时针旋转矩阵90°的几种方法
- iOS开发,将子线程获取的数据实时更新到UI
- POJ 1470 Closest Common Ancestors
- Deep Learning---Overview
- 输出数中最小的一个数在最后!!!
- [置顶] js日期处理---计算自然月、指定自然月某一天、获取前一天和后一天、判断闰年、当月最后一天日期、月末最后一天
- [POJ 1149]PIGS[最大流][建图]
- Spring的jar包描述
- 使用Struts实现防止表单重复提交
- c的详细学习(3)数据的输入输出
- JS判断元素类型
- 算法总结(0)目录式概括
- JAVA中String的常用方法?
- ListView的异步加载图片问题与优化
- 【JQuery】使用hover()方法切换事件
- 妙味课堂——HTML+CSS(第一课)
- Could not start GlassFish Server 4.1 occupied by null