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; }
添加两点,一点和第一列所有点合并,另一点和最后一列所有点合并,如果这两点在一个集合内了,说明两列内有点在一个集合;