• hdu5652:India and China Origins(并查集)


      倒序操作用并查集判断是否连通,新技能get√(其实以前就会了

      这题细节很多。。。搞得整个程序都是调试输出,几度看不下去想要重写

      并查集到现在大概掌握了两个基本用途:判断是否连通 / 路径压缩(上一篇blog)UPD:判断某个区间是否被覆盖

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #define ll long long 
    using namespace std;
    const int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1},maxn=500010;
    int n,m,china,india,T,q,fa[maxn],x[maxn],y[maxn];
    bool v[510][510],map[510][510],map2[510][510];
    char s[maxn];
    void read(int &k)
    {
        int f=1;k=0;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    int gf(int x){return fa[x]==x?x:fa[x]=gf(fa[x]);} 
    int bh(int x,int y)
    {
        if(x==0)return n*m+1;
        if(x==n+1)return n*m+2;
        return (x-1)*m+y;
    }
    void dfs(int x,int y)
    {
        v[x][y]=1;
        for(int i=1;i<=4;i++)
        {
            int nx=x+dx[i],ny=y+dy[i];
            if(nx>n||nx<1||ny>m||ny<1)continue;
            if((!v[nx][ny])&&(!map[nx][ny])&&(!map2[nx][ny]))
            fa[gf(bh(nx,ny))]=gf(bh(x,y)),dfs(nx,ny);
        }
    }
    int main()
    {
        read(T);
        while(T--)
        {
            memset(v,0,sizeof(v));
            memset(map,0,sizeof(map));
            memset(map2,0,sizeof(map2));
            read(n);read(m);china=n*m+1;india=n*m+2;
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                for(int j=0;j<m;j++)
                map[i][j+1]=s[j]-'0';
            }
            read(q);
            for(int i=1;i<=q;i++)
            {
                read(x[i]);read(y[i]);
                x[i]++;y[i]++;
                map2[x[i]][y[i]]=1;
            }
            for(int i=1;i<=n*m+2;i++)fa[i]=i;
            for(int i=1;i<=m;i++)
            if((!map[1][i])&&(!v[1][i])&&(!map2[1][i]))fa[gf(bh(1,i))]=gf(china),dfs(1,i);
            for(int i=1;i<=m;i++)
            if((!map[n][i])&&(!v[n][i])&&(!map2[n][i]))fa[gf(bh(n,i))]=gf(india),dfs(n,i);
            for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
            if((!map[i][j])&&(!v[i][j])&&(!map2[i][j]))dfs(i,j);
            if(gf(china)==gf(india))printf("-1
    ");
            else
            for(int i=q;i;i--)
            {
                map2[x[i]][y[i]]=0;
                for(int j=1;j<=4;j++)
                if((!map[x[i]+dx[j]][y[i]+dy[j]])&&(!map2[x[i]+dx[j]][y[i]+dy[j]]))
                fa[gf(bh(x[i]+dx[j],y[i]+dy[j]))]=gf(bh(x[i],y[i]));
                if(gf(china)==gf(india))
                {
                    printf("%d
    ",i);
                    break;
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Bzoj 3624: [Apio2008]免费道路 (贪心+生成树)
    [ZJOI2008]杀蚂蚁antbuster 题解
    赛前集训的第一个小总结(希望?)
    Bzoj1972: [Sdoi2010]猪国杀 题解(大模拟+耐心+细心)
    Luogu2150 寿司晚宴
    「考试总结2020-08-03」可期
    Luogu4747 [CERC2017]Intrinsic Interval
    BZOJ2839 集合计数
    Luogu5369 [PKUSC2018]最大前缀和
    Luogu5772 [JSOI2016]位运算
  • 原文地址:https://www.cnblogs.com/Sakits/p/7091746.html
Copyright © 2020-2023  润新知