HDU 5652 India and China Origins

来源:互联网 发布:http 411 nginx 编辑:程序博客网 时间:2024/05/21 13:55

题目链接: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这两个点的连通性。


#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 %100000007const 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[n][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;}


0 0
原创粉丝点击