记录编号 143837 评测结果 AAAAAAAAAA
题目名称 [WC 2006] 水管局长 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 2.377 s
提交时间 2014-12-18 08:44:09 内存使用 43.23 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
int getint(){
    char ch=getchar();
    for(;ch>'9'||ch<'0';ch = getchar());
	int tmp = 0;
	for (;'0'<=ch&&ch<='9';ch=getchar()) tmp=tmp*10+int(ch)-48; 
	return tmp;
}
const int SIZEN=100010,SIZEM=1000010,SIZEQ=100010;
inline int min(int a,int b,int c){return min(a,min(b,c));}
int Weight[SIZEM];
class Node{
public:
	int lc,rc,fa;
	int val,mx;
	bool rev;
	void clear(int t){
		lc=rc=fa=0;
		val=mx=t;
		rev=0;
	}
	Node(){clear(0);}
	#define lc(x) Tree[x].lc
	#define rc(x) Tree[x].rc
	#define fa(x) Tree[x].fa
	#define val(x) Tree[x].val
	#define mx(x) Tree[x].mx
	#define rev(x) Tree[x].rev
};
Node Tree[SIZEN+SIZEM];
bool Is_Root(int x){
	return lc(fa(x))!=x&&rc(fa(x))!=x;
}
void Push_Down(int x){
	if(!x) return;
	if(rev(x)){
		swap(lc(x),rc(x));
		rev(lc(x))^=1;rev(rc(x))^=1;
		rev(x)=0;
	}
}
void Update(int x){
	if(!x) return;
	mx(x)=val(x);
	if(Weight[mx(lc(x))]>Weight[mx(x)]) mx(x)=mx(lc(x));
	if(Weight[mx(rc(x))]>Weight[mx(x)]) mx(x)=mx(rc(x));
}
void Zig(int x){//右旋
	int y=fa(x),z=fa(y);
	if(lc(z)==y) lc(z)=x;
	if(rc(z)==y) rc(z)=x;
	fa(x)=z;
	lc(y)=rc(x);fa(lc(y))=y;
	rc(x)=y;fa(y)=x;
	Update(y);Update(x);
}
void Zag(int x){//左旋
	int y=fa(x),z=fa(y);
	if(lc(z)==y) lc(z)=x;
	if(rc(z)==y) rc(z)=x;
	fa(x)=z;
	rc(y)=lc(x);fa(rc(y))=y;
	lc(x)=y;fa(y)=x;
	Update(y);Update(x);
}
void Splay(int x){
	Push_Down(x);
	while(!Is_Root(x)){
		int y=fa(x),z=fa(y);
		Push_Down(z);Push_Down(y);Push_Down(x);
		if(Is_Root(y)){
			if(lc(y)==x) Zig(x);
			else Zag(x);
			return;
		}
		if(lc(z)==y){
			if(lc(y)==x) Zig(y),Zig(x);
			else Zag(x),Zig(x);
		}
		else{
			if(rc(y)==x) Zag(y),Zag(x);
			else Zig(x),Zag(x);
		}
	}
}
void Access(int x){
	int y=0;
	while(x){
		Splay(x);
		rc(x)=y;
		Update(x);
		y=x;
		x=fa(x);
	}
}
int Get_Root(int x){
	Access(x);
	Splay(x);
	while(lc(x)){
		Push_Down(x);
		x=lc(x);
	}
	return x;
}
void Make_Root(int x){
	Access(x);
	Splay(x);
	rev(x)^=1;
}
void Link(int x,int y){
	Make_Root(y);
	fa(y)=x;
	Splay(y);
}
void Cut(int x,int y){
	Make_Root(x);
	Access(y);
	Splay(y);
	fa(lc(y))=0;lc(y)=0;
	Update(y);
}
int Path_Query(int x,int y){
	Make_Root(x);
	Access(y);
	Splay(y);
	return mx(y);
}
class Edge{
public:
	int u,v,w;
};
bool operator < (Edge a,Edge b){
	return a.w<b.w;
}
Edge E[SIZEM];
class Request{
public:
	int cmd;
	int u,v;
};
Request R[SIZEQ];
map<pair<int,int>,int> lis;
bool broken[SIZEM];
int N,M,Q;
void Cut_Edge(int k){
	Cut(E[k].u,N+k);
	Cut(E[k].v,N+k);
}
void Link_Edge(int k){
	Weight[k]=E[k].w;
	Tree[N+k].clear(k);
	Link(E[k].u,N+k);
	Link(E[k].v,N+k);
}
void Add_Edge(int k){//尝试加入k号边
	int g1=Get_Root(E[k].u),g2=Get_Root(E[k].v);
	if(g1!=g2) Link_Edge(k);
	else{
		int e=Path_Query(E[k].u,E[k].v);
		if(Weight[e]>E[k].w){
			Cut_Edge(e);
			Link_Edge(k);
		}
	}
}
void Make_Tree(void){
	for(int i=1;i<=M;i++)
		if(!broken[i]) Add_Edge(i);
}
void Process(void){
	static int ans[SIZEQ];
	for(int i=Q;i>=1;i--){
		if(R[i].cmd==1){
			int k=Path_Query(R[i].u,R[i].v);
			ans[i]=Weight[k];
		}
		else{
			int k=lis[make_pair(R[i].u,R[i].v)];
			Add_Edge(k);
		}
	}
	for(int i=1;i<=Q;i++)
		if(R[i].cmd==1) printf("%d\n",ans[i]);
}
void Init(void){
	N=getint();M=getint();Q=getint();
	for(int i=1;i<=M;i++){
		E[i].u=getint();E[i].v=getint();E[i].w=getint();
		if(E[i].u>E[i].v) swap(E[i].u,E[i].v);
		lis[make_pair(E[i].u,E[i].v)]=i;
	}
	for(int i=1;i<=Q;i++){
		R[i].cmd=getint();R[i].u=getint();R[i].v=getint();
		if(R[i].u>R[i].v) swap(R[i].u,R[i].v);
		if(R[i].cmd==2) broken[lis[make_pair(R[i].u,R[i].v)]]=true;
	}
}
int main(){
	freopen("tube.in","r",stdin);
	freopen("tube.out","w",stdout);
	Init();
	Make_Tree();
	Process();
	return 0;
}