BZOJ4423: [AMPPZ2013]Bytehattan(并查集,对偶图)

来源:互联网 发布:女网络歌手 编辑:程序博客网 时间:2024/06/06 09:59

传送门

比特哈顿镇有n*n个格点,形成了一个网格图。一开始整张图是完整的。
有k次操作,每次会删掉图中的一条边(u,v),你需要回答在删除这条边之后u和v是否仍然连通。

题解:
因为强制在线,不能倒着来,其实这类连通性问题可以转化为对偶图上的问题。
将原图转化为对偶图,每次原图删边转化为对偶图加边,判断新加的边是否会形成环,若会,说明原图的两个端点在删边后不连通。

#include<bits/stdc++.h>using namespace std;inline int read(){    char ch=getchar();int i=0,f=1;    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}    return i*f;} const int Maxn=1500*1500+50;int n,k,anc[Maxn],last=1;inline int getanc(int x){return anc[x]==x?(x):(anc[x]=getanc(anc[x]));}inline int EastSouth(int x,int y){    if(x==n||y==n)return 0;    return (y-1)*(n-1)+x;}inline int WestSouth(int x,int y){    if(x==n||y==1)return 0;    return (y-2)*(n-1)+x;}inline int EastNorth(int x,int y){    if(x==1||y==n)return 0;    return (y-1)*(n-1)+x-1;}inline bool judge(int x,int y,int t){    int t1,t2;    if(t)t1=WestSouth(x,y),t2=EastSouth(x,y);    else t1=EastNorth(x,y),t2=EastSouth(x,y);    if(getanc(t1)==getanc(t2))return false;    anc[getanc(t1)]=getanc(t2);return true; }int main(){    n=read(),k=read();    for(int i=(n-1)*(n-1);i>=0;i--)anc[i]=i;    for(int i=1;i<=k;i++){        int x,y,bz=0;        static char ch[2];        x=read(),y=read();scanf("%s",ch+1);        if(last){            if(judge(x,y,ch[1]=='E'))bz=1;            else bz=0;        }        x=read(),y=read();scanf("%s",ch+1);        if(!last){            if(judge(x,y,ch[1]=='E'))bz=1;            else bz=0;        }        if(!bz)puts("NIE"),last=0;        else puts("TAK"),last=1;    }}