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
";
#else
    const char LL[]="%lld
";
#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
");
        else printf("NIE
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Gloid/p/9871786.html