BZOJ4423 AMPPZ2013Bytehattan(并查集)
判断网格图中某两点是否被割开,可以将割边视为边区域视为点,转化为可切割这两点的区域是否连通。于是每次判断使两个区域连通后是否会形成环(边界视为连通),若是则说明被两点被割开。并查集维护。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } char getc(){char c=getchar();while (c!='N'&&c!='E') c=getchar();return c;} #define N 1510 int n,m,fa[N*N],last=0; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} int trans(int x,int y) { if (x==0||x==n||y==0||y==n) return 0; return (x-1)*(n-1)+y; } int main() { #ifndef ONLINE_JUDGE freopen("bzoj4423.in","r",stdin); freopen("bzoj4423.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),m=read(); for (int i=0;i<=n*n;i++) fa[i]=i; while (m--) { int x=read(),y=read();char c=getc(); if (last==0) read(),read(),getc(); else x=read(),y=read(),c=getc(); int p=x-(c=='N'),q=y-(c=='E'); int u=find(trans(p,q)),v=find(trans(x,y)); last=find(u)==find(v); fa[u]=v; if (last==0) printf("TAK\n"); else printf("NIE\n"); } return 0; }