India and China Origins---hdu5652(二分 + bfs)或者(并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652
题意:
很久以前,中国和印度之间并没有喜马拉雅山相隔,两国的文化交流很频繁。随着喜马拉雅山海拔逐渐增加,两个地区的交流也越来越少,最终没有了来往。
假设当时的地形和我画的一样,蓝色部分代表海洋,而且当时人们还没有发明轮船。黄色部分代表沙漠,而且沙漠上经常有野鬼散步,所以人们不敢到沙漠中行走。黑色的格子表示山峰,这些山峰都无比高大,所以人无法穿过。白色格子代表平原,
人可以在平原上自由行走。人每次可以向相邻的四个格子走动。 此外,我们的考古学家发现还有一些山峰会逐渐形成,通过研究发现,位置在 (x, y)(x,y) (保证该位置之前没有山峰)的地方在 ii 年后出现了山峰。现在给你若干个位置出现山峰的时间,
你可以计算出中国和印度之间的联系最早被彻底切断的时间吗?
多组测试数据, 第一行为组数T(T≤10)。每组测试数据第一行包含两个数 N, M (1≤N,M≤500), 表示地图的大小。接下来 NN 行长度为 MM 的 0101 字符串。00代表白色格子,11 代表山峰。接下来有 Q(1≤Q≤N×M) 行,
第 i(1≤i≤Q) 两个整数 (x,y),0≤x<N,0≤y<M 表示在第 ii 年 (x,y) 出现了一座山峰。
对于每组测试数据,输出一个数, 表示两国最早失联的时间。如果最终两国之间还有联系则输出 -1。 可以二分所有的时间,找到第一个让上下不连通的那个时间点;时间复杂度较高;
#include <stdio.h>
#include <algorithm>
#include<string.h>
#include<queue>
using namespace std; #define MOD 1000000007
#define N 550
typedef long long LL; char G[N][N];
int m, n, x[N*N], y[N*N]; int dir[][]= { {, }, {-,}, {, }, {, -} }; struct node
{
int x, y;
}; int bfs(int x, int y, char Maps[][N])
{
node p, q;
queue<node> Q;
p.x = x, p.y = y;
Q.push(p); int vis[N][N]; memset(vis, , sizeof(vis));
vis[x][y] = ; while(Q.size())
{
p = Q.front();
Q.pop(); if(p.x == n-)///可以连通;
return ; for(int i=; i<; i++)
{
q.x = p.x+dir[i][];
q.y = p.y+dir[i][]; if(q.x>= && q.x<n && q.y>= && q.y<m && Maps[q.x][q.y]=='' && !vis[q.x][q.y])
{
vis[q.x][q.y] = ;
Q.push(q);
}
}
}
return ;
} int Judge(char Maps[][N])
{
for(int i=; i<m; i++)
{
if(Maps[][i]=='')///枚举所有第一行可以走的点;
{
if( bfs(, i, Maps) )///如果可以连通;
return ;
}
}
return ;
} void Init(char Map[][N], int Mid)
{
memset(Map, , sizeof(Map)); for(int i=; i<n; i++)
for(int j=; j<m; j++)
Map[i][j] = G[i][j]; for(int i=; i<=Mid; i++)
Map[x[i]][y[i]] = '';
} int main()
{
int T, k; scanf("%d", &T); while(T--)
{
scanf("%d %d", &n, &m); for(int i=; i<n; i++)
scanf("%s", G[i]); scanf("%d", &k); for(int i=; i<=k; i++)
scanf("%d %d", &x[i], &y[i]); int L = , R = k, Mid = ; char Map[N][N]; while(L <= R)
{
Mid = (L+R) / ; Init(Map, Mid);///重新构造地图,判断第Mid年加上是否连通; if( !Judge(Map) )///不连通;
R = Mid - ;
else
L = Mid + ;
}
if(L > k) L = -; printf("%d\n", L);
}
return ;
}
/*
15
3 4
1100
0001
0000
2
0 3
2 0
*/
重新做了下一这道题;发现是可以用并查集做的,时间复杂度相当于O(Q)的一共有n*m个点,
我们可以编号为1-n*m我们把中国的区域地方看成编号0,印度的区域地方看成n*m+1;
然后把所有的山峰放上去,把所有(i,j)位置能到达的点(xi, yi)建立到一个集合中去;
倒着消除山峰,建立集合,当发现0和n*m+1在一个集中时,说明是当前山峰阻止了两国,答案就是当前山峰的年份;
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 550
#define PI 4*atan(1.0)
#define mod 110119
#define met(a, b) memset(a, b, sizeof(a))
typedef long long LL; int f[N*N], n, m, x[N*N], y[N*N];
char G[N][N];
int dir[][] = {{-,},{,},{,},{,-}}; int Find(int x)
{
if(x!=f[x])
f[x] = Find(f[x]);
return f[x];
} void Union(int a, int b)
{
int pa = Find(a);
int pb = Find(b);
if(pa != pb)
f[pa] = pb;
} int Cul(int X, int Y)
{
if(Y< || Y>=m) return -;
if(X == -) return ;
if(X == n) return n*m+;
if(G[X][Y] == '') return -;
return X*m + Y + ;
} int main()
{
int T, q;
scanf("%d", &T);
while(T--)
{
scanf("%d %d", &n, &m); for(int i=; i<n; i++)
scanf("%s", G[i]); scanf("%d", &q);
for(int i=; i<=q; i++)
{
scanf("%d %d", &x[i], &y[i]);
G[x[i]][y[i]] = '';
} for(int i=; i<=n*m+; i++)///初始化f;
f[i] = i; for(int i=; i<n; i++)
for(int j=; j<m; j++)
{
if(G[i][j] == '') continue;
int num1 = Cul(i, j);///找到当前点的编号;
for(int k=; k<; k++)///与相邻的四点建立关系;
{
int p = i + dir[k][];
int q = j + dir[k][];
int num2 = Cul(p, q);
if(num2 != -)///-1代表不能联合;
Union(num1, num2);
}
}
for(int i=q; i>; i--)
{
G[x[i]][y[i]] = '';///消除当前山峰;建立联合;
int num1 = Cul(x[i], y[i]);
for(int k=; k<; k++)
{
int p = x[i] + dir[k][];
int q = y[i] + dir[k][];
int num2 = Cul(p, q);
if(num2 != -)
Union(num1, num2);
}
if(Find() == Find(m*n+))///当两点在一个集合中时;找到答案;
{
printf("%d\n", i);
break;
}
}
}
return ;
}
India and China Origins---hdu5652(二分 + bfs)或者(并查集)的更多相关文章
- hdu 5652 India and China Origins(二分+bfs || 并查集)BestCoder Round #77 (div.2)
题意: 给一个n*m的矩阵作为地图,0为通路,1为阻碍.只能向上下左右四个方向走.每一年会在一个通路上长出一个阻碍,求第几年最上面一行与最下面一行会被隔开. 输入: 首行一个整数t,表示共有t组数据. ...
- hdu-5652 India and China Origins(二分+bfs判断连通)
题目链接: India and China Origins Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K ...
- HDU 5652 India and China Origins 二分+并查集
India and China Origins 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5652 Description A long time ...
- hdu5652 India and China Origins(并查集)
India and China Origins Accepts: 49 Submissions: 426 Time Limit: 2000/2000 MS (Java/Others) Memo ...
- hdu 5652 India and China Origins 并查集+二分
India and China Origins Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- 并查集(逆序处理):HDU 5652 India and China Origins
India and China Origins Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU 5652 India and China Origins(并查集)
India and China Origins Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- [CF1386C] Joker (IOI 赛制,分治,整体二分+可回退并查集)
题面 给一个 N N N 点 M M M 边的简单无向图,询问 Q Q Q 次,每次问你把编号在 [ l i , r i ] [l_i,r_i] [li,ri] 之间的边删掉后,该图是否存在奇数环 ...
- (hdu)5652 India and China Origins 二分+dfs
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5652 Problem Description A long time ago there ...
随机推荐
- opencv实例二:缩放一张图片
1.知识补充 const char*, char const*, char*const的区别 事实上这个概念谁都有只是三种声明方式非常相似: Bjarne在他的The C++ Programming ...
- 二分求幂,快速求解a的b次幂
一个引子 如何求得a的b次幂呢,那还不简单,一个for循环就可以实现! void main(void) { int a, b; ; cin >> a >> b; ; i < ...
- iOS: [UITableView reloadData]
在 iTouch4 或者相差不多的 iPhone 上,不建议在 UIViewController 的 viewWillAppear 的方法中放置 UITableView 的 reloadData 方法 ...
- Spring-profile设置
开发环境和生产环境通常采用不同的数据库连接方式,开发环境可以采用侵入式,而生产环境中采用jndi连接池,所以要根据不同环境配置不同的bean,Spring中提供了profile来实现动态生成相应的be ...
- Sprite与屏幕之间的关系
锚点这东西挺怀念的,N年前我在做J2ME手游的时候.屏幕整体的坐标是左上角是00点.X轴向右递增,Y轴向下递增.所有的image也是这个原理.只是unity的触摸屏坐标不是左上角,而是左下角. 所以这 ...
- 更改VS2010的[默认开发语言]
1.菜单-->"工具"-->"导入导出设置".例如以下图: 2.选择"重置全部设置",例如以下图: 3.重置设置,例如以下图: ...
- 九度 1529:棋盘寻宝(递推DP)
题目描述: 现在有一个8*8的棋盘,上面放着64个价值不等的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于1000),一个人的初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应 ...
- day7—直播内容(元昊老师著)
*******************************class animal(object): def __init__(self): self.is_handsome=True def e ...
- /etc/redhat-release
该文件用于记录 RedHat 的发行版本信息 [root@localhost ~]$ cat /etc/redhat-release CentOS release 6.5 (Final)
- 使用Editplus和Dev C++配置C++的编译运行环 境
或许大家会有疑问,为何不直接使用VC;VS;或Dev这些IDE呢?何必舍近求远.主要是因为写程序这么多年来已经习惯了Editplus,包括他的快捷键,语法自动完成,语法提示等等,Editplus用了这 ...