特别经典的一个题,还有一种方法就是二分+bfs

题意:空间内n*m个点,每个点是0或者1,0代表此点可以走,1代表不能走。接着经过q年,每年一个坐标表示此点不能走。问哪年开始图上不能出现最上边不能到达最下边的情况了

图上连通性可以使用并查集判断,但是并查集不善于删边,却善于添边。所以我们倒着来想就是离线倒序添边(横向并查,再纵向并查),当某次判断时图已经连通,就结束。

我使用二维并查集,其实就是使用结构体代替一维数组。接着就是每次一定要从x轴小的点到达x轴大的点,最后注意添边时,我们需要此点向四个方向判断添边

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
struct node
{
int xx,yy;
} fat[Max][Max]; //二维并查集
int xx1[Max*Max],yy1[Max*Max];
char str[Max][Max];
int dir[][]= {{,},{-,},{,},{,-}}; //四个方向
void Init(int n,int m)
{
for(int i=; i<n; ++i)
{
for(int j=; j<m; ++j)
{
fat[i][j].xx=i;
fat[i][j].yy=j;
}
}
return ;
}
node Find(int x,int y)
{
if(x==fat[x][y].xx&&y==fat[x][y].yy)
return fat[x][y];
return fat[x][y]=Find(fat[x][y].xx,fat[x][y].yy);
}
int Union(int xx1,int yy1,int xx2,int yy2)//合并两个二维并查集
{
//printf("%d %d %d %d\n",xx1,yy1,xx2,yy2);
node xy1=Find(xx1,yy1);
node xy2=Find(xx2,yy2);
if(xy1.xx==xy2.xx&&xy1.yy==xy2.yy)
return ;
if(xy1.xx<xy2.xx)//保证向下就好
fat[xy1.xx][xy1.yy]=xy2;
else
fat[xy2.xx][xy2.yy]=xy1;
return ;
}
int Jud(int n,int m)//判断是否连通
{
for(int i=; i<m; ++i)
{
node xy1=Find(,i);//第一行可以到达的最下方位置
if(xy1.xx==n-)
return ;
}
return ;
}
int Solve(int n,int m,int q)
{
for(int i=; i<n; ++i)
{
for(int j=; j<m-; ++j)
{
if(str[i][j]==''&&str[i][j+]=='')
{
int ans=Union(i,j,i,j+);//横向合并
//printf("%d\n",ans);
}
}
}
for(int j=; j<m; ++j)
{
for(int i=; i<n-; ++i)
{
if(str[i][j]==''&&str[i+][j]=='')
{
int ans=Union(i,j,i+,j);//纵向合并
//printf("ver=%d\n",ans);
}
}
}
if(Jud(n,m))
return -;
int p;
for(int i=q-; i>=; --i)
{
p=;
str[xx1[i]][yy1[i]]='';
while(p<)
{
if(xx1[i]+dir[p][]>=&&xx1[i]+dir[p][]<n&&yy1[i]+dir[p][]>=&&yy1[i]+dir[p][]<m&&str[xx1[i]+dir[p][]][yy1[i]+dir[p][]]=='')//需要连接四个方向可行的地方
Union(xx1[i],yy1[i],xx1[i]+dir[p][],yy1[i]+dir[p][]);
p++;
}
if(Jud(n,m))
return i+;
}
return ;
}
int main()
{
int t,n,m,q;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
Init(n,m);
for(int i=; i<n; ++i)
scanf("%s",str[i]);
scanf("%d",&q);
for(int i=; i<q; ++i) //存下来,倒着增加边
{
scanf("%d %d",&xx1[i],&yy1[i]);
str[xx1[i]][yy1[i]]='';
}
printf("%d\n",Solve(n,m,q));
}
return ;
}

HDU 5652 India and China Origins(经典并查集)的更多相关文章

  1. HDU 5652 India and China Origins 二分+并查集

    India and China Origins 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5652 Description A long time ...

  2. HDU 5652 India and China Origins(并查集)

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  3. 并查集(逆序处理):HDU 5652 India and China Origins

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. hdu 5652 India and China Origins 并查集+二分

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  5. hdu 5652 India and China Origins 并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题目大意:n*m的矩阵上,0为平原,1为山.q个询问,第i个询问给定坐标xi,yi,表示i年后这 ...

  6. (hdu)5652 India and China Origins 二分+dfs

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5652 Problem Description A long time ago there ...

  7. hdu 5652 India and China Origins 并查集+逆序

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题意:一张n*m个格子的点,0表示可走,1表示堵塞.每个节点都是四方向走.开始输入初始状态方格, ...

  8. hdu5652:India and China Origins(并查集)

    倒序操作用并查集判断是否连通,新技能get√(其实以前就会了 这题细节很多...搞得整个程序都是调试输出,几度看不下去想要重写 并查集到现在大概掌握了两个基本用途:判断是否连通 / 路径压缩(上一篇b ...

  9. hdu 5652 India and China Origins 二分+bfs

    题目链接 给一个图, 由01组成, 1不能走. 给q个操作, 每个操作将一个点变为1, 问至少多少个操作之后, 图的上方和下方不联通. 二分操作, 然后bfs判联通就好了. #include < ...

随机推荐

  1. 利用FFmpeg生成视频的缩略视频 v8.3

    目前生成视频缩略图的工具大多数是生成静态的图片,为了解决这样的局限性,这 次春节期间搞了个利用 FFMpeg 能生成缩略动态视频的批处理. 把 Make_NxM_videos.bat LED_font ...

  2. codeforces 519C. A and B and Team Training 解题报告

    题目链接:http://codeforces.com/contest/519/problem/C 题目意思:给出 n 个  experienced participants  和 m 个 newbie ...

  3. 【opencv】图片标注文字

    IplImage* pstImg; HI_CHAR as8Title[25];CvFont stTimeFont;//字体信息cvInitFont(&stTimeFont,CV_FONT_HE ...

  4. jquery $(document).ready() 与window.onload的异同

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的.   1.执行时间     ...

  5. 通过xib加载UITableViewCell的新方式

    我们以前通常会这样做 - (UITableViewCell  *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPa ...

  6. [Android Pro] 关于inputStream.available()方法获取文件的总大小

    reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...

  7. September 27th 2016 Week 40th Tuesday

    Friends are lost by calling too often and calling seldom. 交往过密过疏,都会失去朋友. Please mind your own busine ...

  8. oracle TIMESTAMP日期相减

    select extract(day from inter) * 24 * 60 * 60 + extract(hour from inter) * 60 * 60 + extract(minute ...

  9. 已有a,b两个链表,每个链表中的结点包括学号,成绩。要求把两个链表合并。按学号升序排列.

    #include <stdio.h>#define SIZE sizeof(struct student)struct student{       long num;       flo ...

  10. 10.11 cocoapods安装

    手动安装gem 手动下载 rubygem https://rubygems.org/pages/download#formats 10.11 cocoapods安装 sudo gem install ...