• 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;
    }
  • 相关阅读:
    PHP删除文件
    PHP定时执行任务
    PHP设置30秒内对页面的访问次数
    PHP抓取网页内容的几种方法
    QQ,新浪,SNS等公众平台的登录及api操作
    php,javascript设置和读取cookie
    php验证邮箱,手机号是否正确
    php自定义加密和解密
    Linux下安装启动多个Mysql
    linux-gcc 编译时头文件和库文件搜索路径
  • 原文地址:https://www.cnblogs.com/hxer/p/5339562.html
Copyright © 2020-2023  润新知