• bzoj#4423-[AMPPZ2013]Bytehattan【并查集】


    正题

    题目链接:https://darkbzoj.tk/problem/4423


    题目大意

    给出一个(n*n)的网格图,然后四联通的点之间连接。每次删掉一条边求这条边的两个点是否连通。强制在线。

    (1leq nleq 1500,1leq mleq 2n(n-1))


    解题思路

    转换成对偶图之后就可以变成加边判断连通性的问题了。

    一个很简单的理解就是如果新的删去的边在对偶图构成了一个环那么就会被分成环内和环外了。

    时间复杂度(O(malpha(m)))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1600;
    int n,k,fa[N*N];
    int find(int x)
    {return (fa[x]==x)?(x):(fa[x]=find(fa[x]));}
    void Unionm(int x,int y){
    	x=find(x);y=find(y);
    	if(x==y)return;fa[x]=y;
    } 
    int main()
    {
    	scanf("%d%d",&n,&k);
    	bool last=1;
    	for(int i=1;i<=(n+1)*(n+1);i++)fa[i]=i;
    	for(int i=1;i<=n;i++){
    		Unionm(i,i+1);
    		Unionm((i-1)*(n+1)+1,i*(n+1)+1);
    		Unionm(n*(n+1)+i,n*(n+1)+i+1);
    		Unionm((i-1)*(n+1)+n+1,i*(n+1)+n+1);
    	}
    	for(int i=1;i<=k;i++){
    		int x1,x2,y1,y2,x,y,p,q;
    		char op1[2],op2[2],op;
    		scanf("%d%d%s",&x1,&y1,&op1);
    		scanf("%d%d%s",&x2,&y2,&op2);
    		if(last)x=x1,y=y1,op=op1[0];
    		else x=x2,y=y2,op=op2[0];
    		if(op=='N'){
    			p=x*(n+1)+y+1;
    			q=(x-1)*(n+1)+y+1;
    			p=find(p);q=find(q);
    			if(p!=q)last=1,puts("TAK");
    			else last=0,puts("NIE");
    		}
    		else{
    			p=x*(n+1)+y+1;
    			q=x*(n+1)+y;
    			p=find(p);q=find(q);
    			if(p!=q)last=1,puts("TAK");
    			else last=0,puts("NIE");
    		}
    		Unionm(p,q);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C语言常用函数
    信号处理函数误用不可重入函数导致的进程死锁情况
    Shell脚本学习
    文件I/O详解
    字体标记的使用
    无序列表标记
    换行标记的使用
    HTML文件的基本结构
    预格式化标记的使用
    特殊标记的使用
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15114453.html
Copyright © 2020-2023  润新知