zoukankan      html  css  js  c++  java
  • 【BZOJ2049】 [Sdoi2008]Cave 洞穴勘测

    BZOJ2049 [Sdoi2008]Cave 洞穴勘测


    Solution

    看到这种动态连边和动态删边的不就想到LCT?

    直接上就好了.

    好像可以非路径压缩并查集搞,不清楚了.

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define re register
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi()
    {
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=300010;
    string opt,Ask1="Connect",Ask2="Destroy",Ask3="Query";
    struct node
    {
    	int ff,ch[2],rev;
    }t[N];
    int sta[N],top;
    void reverse(int x)
    {
    	swap(t[x].ch[0],t[x].ch[1]);
    	t[x].rev^=1;
    }
    bool isroot(int x)
    {
    	return (t[t[x].ff].ch[0]!=x)&(t[t[x].ff].ch[1]!=x);
    }
    void pushdown(int x)
    {
    	if(!t[x].rev)return;
    	if(t[x].ch[0])reverse(t[x].ch[0]);
    	if(t[x].ch[1])reverse(t[x].ch[1]);
    	t[x].rev^=1;
    }
    //文艺平衡树基本操作.
    void rotate(int x)
    {
    	int y=t[x].ff,z=t[y].ff;
    	int k=t[y].ch[1]==x;
    	if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;//为了防止跳到别的Splay上去.
    	t[x].ff=z;
    	t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
    	t[x].ch[k^1]=y;t[y].ff=x;
    }
    void splay(int x)
    {
    	sta[++top]=x;
    	for(int pos=x;!isroot(pos);pos=t[pos].ff)sta[++top]=t[pos].ff;
    	while(top)pushdown(sta[top--]);
    	while(!isroot(x))
    	{
    		int y=t[x].ff,z=t[y].ff;
    		if(!isroot(y))//和rotate是一个道理
    			(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
    		rotate(x);
    	}
    }
    void access(int x)
    {
    	for(int y=0;x;y=x,x=t[x].ff)splay(x),t[x].ch[1]=y;
    }
    void makeroot(int x)
    {
    	access(x);
    	splay(x);
    	reverse(x);
    }
    int findroot(int x)
    {
    	access(x);splay(x);
    	while(t[x].ch[0])x=t[x].ch[0];
    	return x;
    }
    void split(int x,int y)
    {//分割出x,y的路径.
    	makeroot(x);
    	access(y);
    	splay(y);
    }
    void link(int x,int y)
    {
    	makeroot(x);
    	t[x].ff=y;
    }
    void cut(int x,int y)
    {
    	split(x,y);
    	t[y].ch[0]=t[x].ff=0;
    }
    int main()
    {
    	int n,m;
    	n=gi();m=gi();
    	while(m--)
    	{
    		int u,v;cin>>opt;
    		scanf("%d%d",&u,&v);
    		if(opt==Ask1){
    			if(findroot(u)!=findroot(v)){
    				link(u,v);
    			}
    		}
    		if(opt==Ask2)
    			cut(u,v);
    		if(opt==Ask3){
    			if(findroot(u)==findroot(v))puts("Yes");
    			else puts("No");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Swing编程之helloworld
    spring boot集成redis缓存
    Redis安装与运行讲解
    使用IDEA创建Spring boot项目,集成mybaits。并进行简单的数据库查询操作
    SQL字符串拼接FOR XML PATH
    Webservice大文件断点续传
    SQL查询库、表,列等的一些操作
    SQL列转行,行转列实现
    写一个发布Windows服务服务的小工具
    使用DocX替代COM组件的实现
  • 原文地址:https://www.cnblogs.com/mleautomaton/p/10338987.html
Copyright © 2011-2022 走看看