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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652

题意:一张n*m个格子的点,0表示可走,1表示堵塞。每个节点都是四方向走。开始输入初始状态方格,之后输入Q个操作,表示第(x,y)个格子由0变为1;问你在第几次时不能由最下的一行到最上面的一行。中国在最上面一行的上面,印度在最下面一行的下面;如果最终还是连通的,输出-1;

思路:直接离线逆序处理,用并查集维护;

#include<bits/stdc++.h>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
typedef __int64 ll;
typedef unsigned int uint;
template<typename T>
void read1(T &m)
{
    T x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
    if(a>9) out(a/10);
    putchar(a%10+'0');
}
int T,kase = 1,i,j,k,n,m;
const int N = 507;
char s[N][N];
queue<PII> pq;
inline bool check(int nx,int ny)
{
    if(nx < 0 || nx >= n || ny < 0 || ny >= m) return false;
    return true;
}
int dir[2][4] = {{0,1,0,-1},{1,0,-1,0}};
int f[N*N];
int Find(int a){return a==f[a]?f[a]:f[a]=Find(f[a]);}
void _union(int a,int b){int p = Find(a),q = Find(b);f[p] = q;}
int idx(int r,int c) {return r*m+c;}
void BFS(int r,int c)
{
    pq.push({r,c});
    int d = Find(idx(r,c));
    while(!pq.empty()){
        r = pq.front().A,c = pq.front().B;pq.pop();
        for(int i = 0;i < 4;i++){
            int x = r + dir[0][i] , y = c + dir[1][i];
            int id = Find(idx(x,y));
            if(!check(x,y) || s[x][y] == '1' || id == d) continue;
            f[id] = d;
            pq.push({x,y});
        }
    }
}
int x[N*N],y[N*N];
int main()
{
    //freopen("data.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    read1(T);
    while(T--){
        read2(n,m);
        int tot = n*m;
        rep1(i,0,tot+2) f[i] = i;
        rep0(i,0,n) scanf("%s",s[i]);
        int Q;
        read1(Q);
        rep1(i,1,Q){
            read2(x[i],y[i]);
            s[x[i]][y[i]] = '1';
        }
        rep0(i,0,n) rep0(j,0,m)if(s[i][j] == '0'){
            int index = idx(i,j);
            if(f[index] == index){
                BFS(i,j);
            }
        }
        rep0(i,0,m) _union(i,tot+1);
        rep0(i,0,m) _union(idx(n-1,i),tot+2);
        if(f[tot+1] == f[tot+2]){
            puts("-1");
            continue;
        }
        rep_1(i,Q,1){
            s[x[i]][y[i]] = '0';
            BFS(x[i],y[i]);
            if(Find(tot+1) == Find(tot+2)){
                out(i);
                puts("");
                break;
            }
        }
    }
    return 0;
}

 

posted @ 2016-03-31 00:10  hxer  阅读(154)  评论(0编辑  收藏  举报