记录编号 333779 评测结果 AAAAAAAAAA
题目名称 [WC 2006] 水管局长 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 4.017 s
提交时间 2016-10-31 14:22:57 内存使用 37.50 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int N=500010;
//edge chapter
struct edge{int f,t,l,p,T;}w[N];
bool cmp(const edge &x,const edge &y){
	return x.T==y.T?x.l<y.l:x.T>y.T;
}
int n,m,q,head[N],tail[N],next[N];
void add(int i){
	w[i+m]=w[i];swap(w[i].f,w[i].t);
	int f=w[i].f,t=w[i].t;
	if (!head[f]) head[f]=tail[f]=i;
		else tail[f]=next[tail[f]]=i;
	if (!head[t]) head[t]=tail[t]=i+m;
		else tail[t]=next[tail[t]]=i+m;
}
//link cut tree chapter
int son[N][2],fa[N],v[N],mp[N],cnt,E[N];//E[x]表示边权点对应的边标号
bool root[N],rev[N];
#define lc son[x][0]
#define rc son[x][1]
void New(int i){
	v[cnt]=w[i].l;root[cnt]=1;mp[cnt]=cnt;E[cnt]=i;
	w[i].p=w[i<=m?i+m:i-m].p=cnt;
}
void update(int x){
	mp[x]=x;
	if (v[mp[lc]]>v[mp[x]]) mp[x]=mp[lc];
	if (v[mp[rc]]>v[mp[x]]) mp[x]=mp[rc]; 
}
void pushdown(int x){
	if (rev[x]){
		swap(son[lc][0],son[lc][1]);
		swap(son[rc][0],son[rc][1]);
		rev[lc]^=1;rev[rc]^=1;
		rev[0]=rev[x]=0;
	}
}
void rotate(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);
	while (!root[x]){
		int y=fa[x],z=fa[y];
		pushdown(z);pushdown(y);pushdown(x);
		if (root[y]){rotate(x);return;}
		if (x==son[y][0]) rotate(y==son[z][0]?y:x);
			else rotate(y==son[z][1]?y:x);
		rotate(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 make_root(int x){
	access(x);
	rev[x]^=1;
	swap(lc,rc);
}
void cut(int x,int y){
	make_root(y);access(x);
	root[y]=1;lc=fa[y]=0;
	update(x);
}
void link(int x,int y,int i){
	make_root(x);
	fa[fa[x]=++cnt]=y;
	New(i);
}
//init chapter
map<pair<int,int>,int> M;
int f[N];int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void dfs(int x){
	for (int i=head[x];i;i=next[i])
	if (!fa[w[i].t]){
		fa[fa[w[i].t]=++cnt]=x;
		New(i);dfs(w[i].t);
	}
}
struct ask{int k,x,y,ans;}Q[N];
int main()
{
	freopen("tube.in","r",stdin);
	freopen("tube.out","w",stdout);
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=m;i++){
		scanf("%d%d%d",&w[i].f,&w[i].t,&w[i].l);
		w[i].T=q+1;
		M[make_pair(w[i].f,w[i].t)]=M[make_pair(w[i].t,w[i].f)]=i;
	}
	for (int i=1;i<=q;i++){
		scanf("%d%d%d",&Q[i].k,&Q[i].x,&Q[i].y);
		if (Q[i].k==2) w[M[make_pair(Q[i].x,Q[i].y)]].T=i;
	}
	//init
	sort(w+1,w+m+1,cmp);
	for (int i=1;i<=n;i++) root[i]=1,mp[i]=f[i]=i;
	for (int i=1;i<=m;i++)
	if (w[i].T==q+1){
		int a=find(w[i].f),b=find(w[i].t);
		if (a!=b){f[a]=b;add(i);}
	}
	cnt=n;fa[1]=1;dfs(1);fa[1]=0;
	//solve
	int pos=1;while (w[pos].T==q+1) pos++;
	for (int i=q;i;i--){
		int x=Q[i].x,y=Q[i].y;
		make_root(x);
		access(y);
		if (Q[i].k==1) Q[i].ans=v[mp[y]];
		else{
			if (v[mp[y]]>=w[pos].l){
				int e=E[mp[y]];
				cut(w[e].f,w[e].p);
				cut(w[e].t,w[e].p);
				link(x,y,pos);
			}
			pos++;
		}
	}
	for (int i=1;i<=q;i++)
	if (Q[i].k==1) printf("%d\n",Q[i].ans);
	return 0;
}