[ZJOI2012]网络 LCT

lct忘了。。重新学习。

链接:https://www.luogu.org/problemnew/show/P2173

每个颜色开个lct即可。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+100;
const int C=12;

int a[N];
map<int,int>hav[N];
int n,m,c,k;

struct LCT{
	int ch[N][2],fa[N],mx[N],w[N],du[N];bool rev[N];
	void in()
	{
		memset(ch,0,sizeof ch),memset(fa,0,sizeof fa);
		memset(du,0,sizeof du),memset(rev,0,sizeof rev);
		for(int i=1;i<=n;i++)mx[i]=w[i]=a[i];
	}
	int get(int x)
	{
		if(!fa[x])return -1;
		if(ch[fa[x]][0]==x)return 0;
		if(ch[fa[x]][1]==x)return 1;
		return -1;
	}
	void push_up(int x)
	{
		mx[x]=w[x];
		if(ch[x][0])mx[x]=max(mx[x],mx[ch[x][0]]);
		if(ch[x][1])mx[x]=max(mx[x],mx[ch[x][1]]);
	}
	void R(int x)
	{
		swap(ch[x][0],ch[x][1]);
		rev[x]^=1;
	}
	void push_down(int x)
	{
		if(x&&rev[x])
		{
			if(ch[x][0])R(ch[x][0]);
			if(ch[x][1])R(ch[x][1]);
			rev[x]=0;
		}
	}
	void push_all(int x)
	{
		if(get(x)!=-1)push_all(fa[x]);
		push_down(x);
	}
	void rot(int x)
	{
		int fx=fa[x],gx=fa[fx],op=get(x),fop=get(fx);
		ch[fx][op]=ch[x][op^1],fa[ch[x][op^1]]=fx;
		ch[x][op^1]=fx,fa[fx]=x;if(fop!=-1)ch[gx][fop]=x;fa[x]=gx;
		push_up(fx),push_up(x);
	}
	void splay(int x)
	{
		push_all(x);
		for(int fx=fa[x];get(x)!=-1;rot(x),fx=fa[x])
			if(get(fx)!=-1)get(x)==get(fx)?rot(fx):rot(x);
	}
	void access(int x)
	{
		for(int y=0;x;y=x,x=fa[x])
			splay(x),ch[x][1]=y,push_up(x);
		//cerr<<'?'<<'\n';
	}
	void make_rt(int x)
	{access(x),splay(x),R(x);}
	int find_rt(int x)
	{
		access(x),splay(x);
		for(;ch[x][0];)push_down(x),x=ch[x][0];
		splay(x);
		return x;
	}
	int line(int x,int y,int op)
	{
		if(du[x]==2||du[y]==2){if(op)puts("Error 1.");return 0;}
		make_rt(x);
		if(find_rt(y)==x){if(op)puts("Error 2.");return 0;}
		fa[x]=y,du[x]++,du[y]++;
		if(op)puts("Success.");
		return 1;
	}
	void cut(int x,int y)
	{
		make_rt(x),access(y),splay(y);
		ch[y][0]=0,fa[x]=0,du[x]--,du[y]--;
		push_up(y);
	}
	void cg(int x,int y)
	{splay(x),w[x]=y,push_up(x);}
	void qry(int x,int y)
	{
		//if(x==9&&y==6)cerr<<"!!"<<'\n';
		make_rt(x);
		//if(x==9&&y==6)cerr<<"!!"<<'\n';
		if(find_rt(y)!=x){puts("-1");return;}
		splay(y);
		printf("%d\n",mx[y]);
	}
}lct[C];


int main()
{
	scanf("%d%d%d%d",&n,&m,&c,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=c;i++)
		lct[i].in();
	int x,y,w,op;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&w);
		++w;
		hav[x][y]=hav[y][x]=w;
		lct[w].line(x,y,0);
	}
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&op);
		if(op==0)
		{
			scanf("%d%d",&x,&y);
			for(int j=1;j<=c;j++)
				lct[j].cg(x,y);
		}
		if(op==1)
		{
			scanf("%d%d%d",&x,&y,&w),++w;
			if(hav[x][y]==w){puts("Success.");continue;}
			if(!hav[x][y]){puts("No such edge.");continue;}
			if(lct[w].line(x,y,1)==1)
			{
				lct[hav[x][y]].cut(x,y);
				hav[x][y]=hav[y][x]=w;
			}
		}
		if(op==2)
		{
			scanf("%d%d%d",&w,&x,&y),++w;
			lct[w].qry(x,y);
		}
	}
}

 

上一篇:python 刷题 数字翻转


下一篇:Linux查看系统设备