# bzoj2594 [Wc2006]水管局长数据加强版

【题解】

# include <map>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1.5e6 + 10, N = 1e5 + 10;
const int mod = 1e9+7;

// 性质：u->v路径上最大边最小，一定在MST上。

int n, m, ans[N];
bool v[M];
map<int, int> mp[N];

inline int getint() {
char ch = getchar(); int x = 0;
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = (x<<3) + (x<<1) + ch - '0', ch = getchar();
return x;
}

struct pa {
int t, a, b;
pa() {}
pa(int t, int a, int b) : t(t), a(a), b(b) {}
}q[N];

struct edge {
int u, v, t;
edge() {}
edge(int u, int v, int t) : u(u), v(v), t(t) {}
friend bool operator < (edge a, edge b) {
return a.t < b.t;
}
}e[M];

struct us {
int fa[N], n;
inline void set(int _n) {
n = _n; for (int i=1; i<=n; ++i) fa[i] = i;
}
inline int getf(int x) {
return fa[x] == x ? x : fa[x] = getf(fa[x]);
}
inline void un(int fx, int fy) {
fa[fx] = fy;
}
}U;

struct LCT {
int ch[M][2], fa[M], val[M], mx[M], id[M];
bool rev[M];
inline void set() {
memset(ch, 0, sizeof ch);
memset(fa, 0, sizeof fa);
memset(val, 0, sizeof val);
memset(mx, 0, sizeof mx);
memset(rev, 0, sizeof rev);
memset(id, 0, sizeof id);
}
# define ls ch[x][0]
# define rs ch[x][1]
inline void up(int x) {
if(!x) return ;
mx[x] = val[x]; id[x] = x;
if(mx[x] < mx[ls]) mx[x] = mx[ls], id[x] = id[ls];
if(mx[x] < mx[rs]) mx[x] = mx[rs], id[x] = id[rs];
}
inline void pushrev(int x) {
if(!x) return ;
swap(ls, rs);
rev[x] ^= 1;
}
inline void down(int x) {
if(!x || !rev[x]) return ;
pushrev(ls), pushrev(rs);
rev[x] = 0;
}
# undef ls
# undef rs
inline bool isrt(int x) {
return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
}
inline void rotate(int x) {
int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
if(!isrt(y)) ch[z][ch[z][1] == y] = x;
fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z;
ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
up(y); up(x);
}
int st[M];
inline void splay(int x) {
int stn = 0, tx = x;
while(!isrt(tx)) st[++stn] = tx, tx = fa[tx];
st[++stn] = tx;
for (int i=stn; i; --i) down(st[i]);
while(!isrt(x)) {
int y = fa[x], z = fa[y];
if(!isrt(y)) {
if((ch[y][0] == x) ^ (ch[z][0] == y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
inline int access(int x) {
int t = 0;
for (; x; t = x, x = fa[x]) {
splay(x);
ch[x][1] = t;
up(x);
}
return t;
}
inline void makeroot(int x) {
access(x); splay(x); pushrev(x);
}
inline void link(int x, int y) {
makeroot(x); fa[x] = y;
}
inline int cut(int x, int y) {
makeroot(x); access(y); splay(y); ch[y][0] = fa[x] = 0; up(y);
}
inline int split(int x, int y) {
makeroot(x); access(y); splay(y); return y;
}
}T;

int main() {
n = getint(), m = getint();
int Q = getint(); U.set(n); T.set();
for (int i=1; i<=m; ++i) e[i].u = getint(), e[i].v = getint(), e[i].t = getint();
sort(e+1, e+m+1);
for (int i=1; i<=m; ++i) mp[e[i].u][e[i].v] = i, mp[e[i].v][e[i].u] = i;
for (int i=1; i<=Q; ++i) {
q[i].t = getint(); q[i].a = getint(), q[i].b = getint();
if(q[i].t == 2) v[mp[q[i].a][q[i].b]] = 1;
}
for (int i=1, x; i<=m; ++i) {
if(v[i]) continue;
int fu = U.getf(e[i].u), fv = U.getf(e[i].v);
if(fu != fv) {
x = i+n;
U.un(fu, fv);
T.val[x] = e[i].t;
}
}
for (int i=Q, x, t, y; i; --i) {
x = T.split(q[i].a, q[i].b);
if(q[i].t == 1) ans[i] = T.mx[x];
else {
y = n + mp[q[i].a][q[i].b];
t = e[y-n].t;
if(t < T.mx[x]) {
T.val[y] = t; t = T.id[x];
T.cut(t, e[t-n].u);
T.cut(t, e[t-n].v);
}