• HDU 5652 India and China Origins 并查集


    分析:这是一个连通性的问题。你会发现如果将所有操作逆序来看的话就很容易用并查集来处理了。 首先把所有的山峰都加到图中,然后逆序处理每个操作:

    对某次操作,在图中删除该位置的山峰,然后判断两个点是否联通,一旦联通就得到了结果。 这里需要对China和India分别新建一个对应的节点。

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=1e3+5;
    const int INF=0x3f3f3f3f;
    char s[N][N];
    struct Que
    {
        int x,y;
    } p[N*N];
    int dx[4]= {0,0,-1,1};
    int dy[4]= {-1,1,0,0};
    int fa[N*N],r[N*N];
    int find(int x)
    {
        if(x==fa[x])return x;
        return fa[x]=find(fa[x]);
    }
    void fun(int x,int y)
    {
        x=find(x),y=find(y);
        if(x!=y)
        {
            if(r[x]>r[y])
            {
                fa[y]=x;
            }
            else if(r[x]<r[y])
            {
                fa[x]=y;
            }
            else fa[y]=x,++r[x];
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,m,q;
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; ++i)
                scanf("%s",s[i]+1);
            scanf("%d",&q);
            for(int i=1; i<=q; ++i)
            {
                scanf("%d%d",&p[i].x,&p[i].y);
                ++p[i].x,++p[i].y;
                s[p[i].x][p[i].y]='1';
            }
            for(int i=1; i<=n*m+2; ++i)fa[i]=i,r[i]=0;
            int k1=n*m+1,k2=n*m+2;
            for(int i=1; i<=m; ++i)
            {
                if(s[1][i]=='0')fun(k1,i);
                if(s[n][i]=='0')fun(k2,(n-1)*m+i);
            }
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<=m; ++j)
                {
                    if(s[i][j]=='1')continue;
                    if(i<n&&s[i+1][j]=='0')fun((i-1)*m+j,i*m+j);
                    if(j<m&&s[i][j+1]=='0')fun((i-1)*m+j,(i-1)*m+j+1);
                }
            }
            if(find(k1)==find(k2))
            {
                printf("-1
    ");
                continue;
            }
            int ans=0;
            for(int i=q; i>0; --i)
            {
                int x=p[i].x,y=p[i].y;
                s[x][y]='0';
                if(x==1)fun(k1,y);
                if(x==n)fun(k2,(n-1)*m+y);
                for(int j=0; j<4; ++j)
                {
                    int xx=x+dx[j];
                    int yy=y+dy[j];
                    if(xx<1||xx>n||yy<1||yy>m)continue;
                    if(s[xx][yy]=='1')continue;
                    fun((x-1)*m+y,(xx-1)*m+yy);
                }
                if(find(k1)==find(k2))
                {
                    ans=i;
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HERO 3
    office的一些应用,
    网页之间的参数传弟
    一个好的数码网站
    C++遍历中删除std::hash_map元素问题
    【转】Asio与shared_ptr的一些注意事项
    delphi的字节对齐
    paypal的即时付款通知参数列表(PDT)
    vs2010下libevent的使用
    mysql 数据库 left join,right join, inner join 知识
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5324207.html
Copyright © 2020-2023  润新知