#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; inline void Read(int &Num) { char c = getchar(); while (c < ‘0‘ || c > ‘9‘) c = getchar(); Num = c - ‘0‘; c = getchar(); while (c >= ‘0‘ && c <= ‘9‘) { Num = Num * 10 + c - ‘0‘; c = getchar(); } } inline int gmax(int a, int b) {return a > b ? a : b;} inline int gmin(int a, int b) {return a < b ? a : b;} const int MaxN = 100000 + 5, MaxM = 1000000 + 5, MaxT = 1100000 + 5, MaxQ = 100000 + 5; int n, m, q, Top; int Father[MaxT], Son[MaxT][2], V[MaxT], T[MaxT], f[MaxN], Size[MaxN], Ans[MaxQ]; bool isRoot[MaxT], Rev[MaxT]; struct ES { int u, v, w, Idx; bool Del; ES() {} ES(int x, int y) { u = x; v = y; if (u > v) swap(u, v); } } E[MaxM]; inline bool operator < (ES e1, ES e2) { return (e1.u < e2.u) || (e1.u == e2.u && e1.v < e2.v); } struct QR { int f, x, y, Pos; } Q[MaxQ]; inline bool Cmp(ES e1, ES e2) { return e1.w < e2.w; } inline int Find(int x) { int i, j, k; j = x; while (j != f[j]) j = f[j]; i = x; while (i != j) { k = i; i = f[i]; f[k] = j; } return j; } inline void UN(int x, int y) { if (Size[x] == Size[y]) ++Size[x]; if (Size[x] > Size[y]) f[y] = x; else f[x] = y; } /********************* LCT Begin *********************/ inline void Update(int x) { if (V[T[Son[x][0]]] > V[T[Son[x][1]]) T[x] = T[Son[x][0]]; else T[x] = T[Son[x][1]]; if (V[x] > V[T[x]]) T[x] = x; } inline void Reverse(int x) { Rev[x] = !Rev[x]; swap(Son[x][0], Son[x][1]); } inline void PushDown(int x) { if (!Rev[x]) return; Rev[x] = false; if (Son[x][0]) Reverse(Son[x][0]); if (Son[x][1]) Reverse(Son[x][1]); } inline int GetDir(int x) { if (x == Son[Father[x]][0]) return 0; else return 1; } void Rotate(int x) { int y = Father[x], f; PushDown(y); PushDown(x); if (x == Son[y][0]) f = 1; else f = 0; if (isRoot[y]) { isRoot[y] = false; isRoot[x] = true; } else { if (y == Son[Father[y]][0]) Son[Father[y]][0] = x; else Son[Father[y]][1] = x; } Father[x] = Father[y]; Son[y][f ^ 1] = Son[x][f]; if (Son[x][f]) Father[Son[x][f]] = y; Son[x][f] = y; Father[y] = x; Update(y); Update(x); } void Splay(int x) { int y; while (!isRoot[x]) { y = Father[x]; if (isRoot[y]) { Rotate(x); break; } if (GetDir(y) == GetDir(x)) Rotate(y); else Rotate(x); Rotate(x); } } int Access(int x) { int y = 0; while (x != 0) { Splay(x); PushDown(x); if (Son[x][1]) isRoot[Son[x][1]] = true; Son[x][1] = y; if (y) isRoot[y] = false; Update(x); y = x; x = Father[x]; } return y; } inline void Make_Root(int x) { int t = Access(x); Reverse(t); } /********************* LCT End *********************/ int main() { scanf("%d%d%d", &n, &m, &q); int a, b, c, t; for (int i = 1; i <= m; ++i) { Read(a); Read(b); Read(c); E[i] = ES(a, b); E[i].w = c; } sort(E + 1, E + m + 1, Cmp); // by ES.w for (int i = 1; i <= m; ++i) { E[i].Idx = i; V[n + i] = E[i].w; T[n + i] = n + i; } for (int i = 1; i <= n + m; ++i) { isRoot[i] = true; Father[i] = 0; } sort(E + 1, E + m + 1); // by ES.u && ES.v for (int i = 1; i <= q; ++i) { Read(Q[i].f); Read(Q[i].x); Read(Q[i].y); if (Q[i].f == 2) { t = lower_bound(E + 1, E + m + 1, ES(Q[i].x, Q[i].y)) - E; E[t].Del = true; Q[i].Pos = E[t].Idx; } else ++Top; } for (int i = 1; i <= n; ++i) { f[i] = i; Size[i] = 1; } sort(E + 1, E + m + 1, Cmp); int Cnt = 0, fx, fy; for (int i = 1; i <= m; ++i) { if (E[i].Del) continue; fx = Find(E[i].u); fy = Find(E[i].v); if (fx == fy) continue; UN(fx, fy); Link(E[i].u, n + i); Link(E[i].v, n + i); if (++Cnt == n - 1) break; } for (int i = q; i >= 1; --i) { Make_Root(Q[i].x); t = Access(Q[i].y); if (Q[i].f == 1) Ans[Top--] = V[T[t]]; else { if (E[Q[i].Pos].w >= V[T[t]]) continue; Cut(Q[i].x, T[t]); Cut(Q[i].y, T[t]); Link(Q[i].x, Q[i].Pos); Link(Q[i].y, Q[i].Pos); } } return 0; }
时间: 2024-11-10 02:36:02