# BZOJ3732：Network（LCT与最小生成树）

给你N个点的无向图 (1 <= N <= 15,000)，记为：1…N。

Input

Output
对每个询问，输出最长的边最小值是多少。

Sample Input
6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1
Sample Output
5
5
5
4
4
7
4
5
Hint
1 <= N <= 15,000

1 <= M <= 30,000

1 <= d_j <= 1,000,000,000

1 <= K <= 15,000

（写LCT写惯了就不想写树剖了有没有

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=50010;
struct egde{
int x,y,val;
}e[maxn];
char c=getchar(); x=0;
for(;c>'9'||c<'0';c=getchar());
for(;c<='9'&&c>='0';c=getchar()) x=(x<<3)+(x<<1)+c-'0';
}
struct LCT
{
int Max[maxn],rev[maxn],ch[maxn][2],fa[maxn],stc[maxn],top;
int isroot(int x){
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
int get(int x){
return ch[fa[x]][1]==x;
}
void pushdown(int x)
{
if(!rev[x]||!x) return ;
swap(ch[x][0],ch[x][1]);
if(ch[x][0]) rev[ch[x][0]]^=1;
if(ch[x][1]) rev[ch[x][1]]^=1;
rev[x]=0;
}
void pushup(int x)
{
Max[x]=x;
if(ch[x][0]&&e[Max[ch[x][0]]].val>e[Max[x]].val) Max[x]=Max[ch[x][0]];
if(ch[x][1]&&e[Max[ch[x][1]]].val>e[Max[x]].val) Max[x]=Max[ch[x][1]];
}
void rotate(int x)
{
int old=fa[x],fold=fa[old],opt=get(x);
if(!isroot(old)) ch[fold][get(old)]=x;
fa[x]=fold;
ch[old][opt]=ch[x][opt^1]; fa[ch[old][opt]]=old;
ch[x][opt^1]=old; fa[old]=x;
pushup(old); pushup(x);
}
void splay(int x)
{
int top=0; stc[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) stc[++top]=fa[i];
for(int i=top;i;i--) pushdown(stc[i]);
for(int f;!isroot(x);rotate(x)){
if(!isroot(f=fa[x]))
rotate(get(x)==get(f)?f:x);
}
}
void access(int x)
{
int rson=0;
for(;x;rson=x,x=fa[x]){
splay(x);
ch[x][1]=rson;
pushup(x);
}
}
int find(int x){ access(x); splay(x); while(ch[x][0]) x=ch[x][0]; return x;}
int query(int x,int y) { make_root(y); access(x);  splay(x); return Max[x]; }
void make_root(int x) { access(x); splay(x); rev[x]^=1; }
void link(int x,int y) { make_root(x); fa[x]=y; splay(x); }
void cut(int x,int y) { make_root(x); access(y); splay(y); fa[x]=ch[y][0]=0; }

}S;
int main()
{
int N,M,Q,u,v,i;
scanf("%d%d%d",&N,&M,&Q);
for(i=1;i<=M;i++){
if(S.find(M+e[i].x)!=S.find(M+e[i].y)){
}
else {
int tmp=S.query(M+e[i].x,M+e[i].y);
if(e[tmp].val>e[i].val){
S.cut(tmp,M+e[tmp].x); S.cut(tmp,M+e[tmp].y);
}
}
}
while(Q--){
}