zoukankan      html  css  js  c++  java
  • hdu 5652 并查集

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5652
    题意:
    给出一个n*m的图,1是山峰,0是平原,还有q个操作,可以把0变成1,问最少前几次操作可以使得图的上端和下端完全阻隔,就是被1隔开。
    分析:
    判断是否完全隔开,就是判断是否1可以从左到右全都连起来,那么可以增加两个点s和e,表示最左端个最右端,如果是1,那么将1的八方是1的点连接起来,然后判断s和e是否连通。这个用并查集比较好做。还看到以一种思路是二分操作+bfs判联通。

    并查集:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=505;
    int dx[]={-1,-1,-1,0,0,1,1,1};
    int dy[]={-1,0,1,-1,1,-1,0,1};
    int fa[N*N];
    char g[N][N];
    int findfa(int x){return x==fa[x]?x:fa[x]=findfa(fa[x]);}
    void unionfa(int x,int y)
    {
        int xx=findfa(x),yy=findfa(y);fa[xx]=yy;
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
            int s=n*m,e=s+1;
            for(int i=0;i<=e;i++)fa[i]=i;
            for(int i=0;i<n;i++)scanf("%s",g[i]);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(g[i][j]=='0')continue;
                    if(j==0)unionfa(s,i*m+j);
                    if(j==m-1)unionfa(e,i*m+j);
                    for(int k=0;k<8;k++){
                        int x=dx[k]+i,y=dy[k]+j;
                        if(x<0||y<0||x>=n||y>=m||g[x][y]=='0')continue;
                        unionfa(x*m+y,i*m+j);
                    }
                }
            }
           // if(findfa(s)==findfa(e)){printf("AAAAAAAAAAAAAA
    ");}
            int q;scanf("%d",&q);
            int ans=-1;
            for(int i=0;i<q;i++){
                int a,b; scanf("%d%d",&a,&b);g[a][b]='1';
                if(ans!=-1)continue;
                if(findfa(s)==findfa(e))ans=i;
                if(b==0)unionfa(s,a*m+b);
                if(b==m-1)unionfa(e,a*m+b);
                for(int k=0;k<8;k++){
                    int x=dx[k]+a,y=dy[k]+b;
                    if(x<0||y<0||x>=n||y>=m||g[x][y]=='0')continue;
                    unionfa(x*m+y,a*m+b);
                }
            }
            if(ans==-1&&findfa(s)==findfa(e))ans=q;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Entity SQL 初入
    ObjectQuery查询及方法
    Entity Framework 的事务 DbTransaction
    Construct Binary Tree from Preorder and Inorder Traversal
    Reverse Linked List
    Best Time to Buy and Sell Stock
    Remove Duplicates from Sorted Array II
    Reverse Integer
    Implement Stack using Queues
    C++中const限定符的应用
  • 原文地址:https://www.cnblogs.com/01world/p/5651242.html
Copyright © 2011-2022 走看看