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;
}

  

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

 

posted @ 2018-04-14 21:16  荒岛的龟  阅读(236)  评论(0编辑  收藏  举报