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

    题意:很久之前,在中国和印度之间有通路,通路可以简化为一个n*m的字符串,0表示能通过,1表示障碍,每过一年就有一个坐标变成1,问你什么时候,通路彻底无法通过;

    解题思路:无向图的连通性,一般直接搜索或者并查集判定,这里用的是并查集,我们把相连的障碍放到一个集合内,然后如果第一列的某点和最后一列的某点也在这个集合内,那么说明,这个通路被障碍堵死了;

    这里要处理下第一列和最后一列的问题,可以选择

    #include<iostream>
    #include<algorithm>
    #define N 605
    using namespace std;
    int next1[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
    int dx[]={-1,-1,-1,0,0,1,1,1};
    int dy[]={-1,0,1,-1,1,-1,0,1};
    int f[N*N];
    char a[N][N];
    int findf(int x)
    {
        if(f[x]==x)
            return x;
        else findf(f[x]);
    }
    void join(int x,int y)
    {
        int t1=findf(x);
        int t2=findf(y);
        if(t1!=t2)
            f[t2]=t1;
    }
    int main()
    {
        int tx,ty;
        int n,m;
        int t;
        int tt;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            int s,e;
            s=n*m;e=s+1;
            for(int i=0;i<=e;i++)
                f[i]=i;
            for(int i=0;i<n;i++)
            {
                join(s,m*i);join(e,m*i+m-1);
            }
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    cin>>a[i][j];
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
            {
                if(a[i][j]=='0')
                    continue;
                for(int k=0;k<8;k++)
                {
                    tx=i+dx[k];ty=j+dy[k];
                    if(tx<0||ty<0||tx>=n||ty>=m||a[tx][ty]=='0')
                    continue;
                    join(i*m+j,tx*m+ty);
                }
            }
            cin>>tt;
            int x,y;
            int flag=-1;
            for(int i=1;i<=tt;i++)
            {
                cin>>x>>y;
                if(flag!=-1)
                    continue;
    
                a[x][y]='1';
                for(int k=0;k<8;k++)
                {
                    tx=x+dx[k];ty=y+dy[k];
                    if(tx<0||ty<0||tx>=n||ty>=m||a[tx][ty]=='0')
                    continue;
                    join(tx*m+ty,x*m+y);
                }
                if(findf(s)==findf(e))
                    flag=i;
            }
            cout<<flag<<endl;
        }
        return 0;
    }
    

      

    添加两点,一点和第一列所有点合并,另一点和最后一列所有点合并,如果这两点在一个集合内了,说明两列内有点在一个集合;

  • 相关阅读:
    MvcApplication 中方法的那点事
    Html 中阻止事件冒泡的三种方法比较
    WPF中 ItemsSource 和DataContext不同点
    解决:Visual Studio 启动就报错退出
    webapi是如何绑定参数的(How WebAPI does Parameter Binding)
    %cd% 和%~dp0%的区别及cd跨盘符切换路径问题
    win10中matlabR2015b安装libsvm
    MATLAB2015b链接MinGW编译器
    网易内推编程题:异或运算求混合颜料的最小种类
    小易喜欢的单词
  • 原文地址:https://www.cnblogs.com/huangdao/p/8835506.html
Copyright © 2011-2022 走看看