记录编号 403668 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2012] 网络 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 2.501 s
提交时间 2017-05-11 08:21:57 内存使用 7.63 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int N=2e4+10,E=2e5+10;
int n,m,c,k,val[N];
int color[E];
map<pair<int,int>,int> M;
struct LCT{
	int w[N],head[N],next[N],edge[N],cnt;
	void add(int f,int t){
		w[++cnt]=t;
		next[cnt]=head[f];
		head[f]=cnt;
		edge[f]++;
	}
	int fa[N],son[N][2],Max[N];
	bool rev[N],root[N];
	#define lc son[x][0]
	#define rc son[x][1]
	void dfs(int x,int Fa){
		root[x]=1;Max[x]=val[x];
		for (int i=head[x];i;i=next[i])
		if (w[i]!=Fa) fa[w[i]]=x,dfs(w[i],x);
	}
	void init(){
		for (int i=1;i<=n;i++)
		if (!root[i]) dfs(i,0);
	}
	void update(int x){
		Max[x]=val[x];
		if (lc) Max[x]=max(Max[x],Max[lc]);
		if (rc) Max[x]=max(Max[x],Max[rc]); 
	}
	void flip(int x){
		swap(lc,rc);rev[x]^=1;
	}
	void pushdown(int x){
		if (rev[x]){
			if (lc) flip(lc);
			if (rc) flip(rc);
			rev[x]=0;
		}
	}
	void rot(int x){
		int y=fa[x],z=fa[y];
		bool b=(x==son[y][1]);
		fa[son[y][b]=son[x][!b]]=y;
		fa[son[x][!b]=y]=x;
		fa[x]=z;
		if (y==son[z][0]) son[z][0]=x;else
		if (y==son[z][1]) son[z][1]=x;
		root[x]=root[y];root[y]=0;
		update(y);update(x);
	}
	void splay(int x){
		pushdown(x);
		for (;!root[x];rot(x)){
			int y=fa[x],z=fa[y];
			pushdown(z);pushdown(y);pushdown(x);
			if (!root[y]) rot((x==son[y][0])==(y==son[z][0])?y:x);
		}
	}
	void access(int x){
		splay(x);
		root[rc]=1;rc=0;
		update(x);
		while (fa[x]){
			int y=fa[x];
			splay(y);
			root[son[y][1]]=1;
			root[son[y][1]=x]=0;
			update(y);
			splay(x);
		}
	}
	void makeroot(int x){
		access(x);flip(x);
	}
	bool islink(int x,int y){
		makeroot(x);
		int z=y;
		while (fa[z]) z=fa[z];
		access(y);
		return z==x;
	}
	void link(int x,int y){
		fa[x]=y;edge[x]++;edge[y]++;
	}
	void cut(int x,int y){
		makeroot(y);
		access(x);
		root[lc]=1;fa[lc]=0;lc=0;
		update(x);
		edge[x]--;edge[y]--;
	}
}lct[10];
int main()
{
	freopen("networkzj.in","r",stdin);
	freopen("networkzj.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&c,&k);
	for (int i=1;i<=n;i++) scanf("%d",&val[i]);
	for (int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d%d",&u,&v,&color[i]);
		M[make_pair(u,v)]=M[make_pair(v,u)]=i;
		lct[color[i]].add(u,v);
		lct[color[i]].add(v,u);
	}
	for (int i=0;i<c;i++) lct[i].init();
	while (k--){
		int tp,u,v,w;
		scanf("%d%d%d",&tp,&u,&v);
		if (!tp){
			for (int i=0;i<c;i++) lct[i].access(u);
			val[u]=v;
			for (int i=0;i<c;i++) lct[i].update(u);
		}
		else scanf("%d",&w);
		if (tp==1){
			int id=M[make_pair(u,v)];
			if (!id){
				puts("No such edge.");
				continue;
			}
			if (w==color[id]){
				puts("Success.");
				continue;
			}
			if (lct[w].edge[u]>1||lct[w].edge[v]>1){
				puts("Error 1.");
				continue;
			}
			if (lct[w].islink(u,v)){
				puts("Error 2.");
				continue;
			}
			lct[color[id]].cut(u,v);
			lct[color[id]=w].link(u,v);
			puts("Success.");
		}
		if (tp==2){
			if (!lct[u].islink(v,w)) puts("-1");
			else printf("%d\n",lct[u].Max[w]);
		}
	}
	return 0;
}