记录编号 215586 评测结果 AAAAAAAAAAAAAA
题目名称 [WC 2006]水管局长数据加强版 最终得分 100
用户昵称 Gravatarppfish 是否通过 通过
代码语言 C++ 运行时间 3.795 s
提交时间 2015-12-23 00:43:28 内存使用 51.78 MiB
显示代码纯文本
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

template<class T>inline void Read(T &x)
{
    int f = 1;
    char t = getchar();
    while (t < '0' || t > '9') {
        if (t == '-') f = -1;
        t = getchar();
    }
    x = 0;
    while (t >= '0' && t <= '9') {
        x = x * 10 + t - '0';
        t = getchar();
    }
    x *= f;
}

template<class T>void print(T &x)
{
    static int q[15], r;
    r = 0;
    do {
        q[++r] = x % 10;
        x /= 10;
    } while (x);
    while (r) putchar('0' + q[r--]);
    putchar('\n');
}

const int maxn = 100005;
const int maxq = 100005;
const int maxm = 1000005;
const int inf = 0x3f3f3f3f;

struct edge {
    int u, v, w, id;
    bool ban;
    void read() { Read(u), Read(v), Read(w); if (u > v) swap(u, v); }
    bool operator < (const edge &rhs) const { return w < rhs.w; }
};

struct node {
    int c[2], fa, mx;
    bool rev;
    node() { c[0] = c[1] = fa = mx = rev = 0; }
} T[maxn + maxm];

int n, m, q;
edge e[maxm], opr[maxq];
int val[maxn + maxm], idx[maxq], fa[maxn];

#define Fa(x) T[T[x].fa]
#define Lc(x) T[T[x].c[0]]
#define Rc(x) T[T[x].c[1]]

bool cmp(edge a, edge b) { return a.u < b.u || (a.u == b.u && a.v < b.v); }

bool isroot(int x) { return x != Fa(x).c[0] && x != Fa(x).c[1]; }

int gmax(const int &a, const int &b) { return val[a] > val[b] ? a : b; }

void update(int x) { T[x].mx = gmax(x, gmax(Lc(x).mx, Rc(x).mx)); }

void setc(int x, int y, bool mark)
{
    if (y) T[y].c[mark] = x;
    if (x) T[x].fa = y;
}

void pushdown(int x)
{
    if (T[x].rev) {
        T[x].rev ^= 1, Lc(x).rev ^= 1, Rc(x).rev ^= 1;
        swap(T[x].c[0], T[x].c[1]);
    }
}

void linkup(int x)
{
    static int line[maxn + maxm], now;
    line[now = 1] = x;
    while (!isroot(x)) line[++now] = T[x].fa, x = T[x].fa;
    while (now) pushdown(line[now --]);
}

void rotate(int x)
{
    if (isroot(x)) return;
    int p = T[x].fa, mark = (x == Fa(x).c[1]);
    if (!isroot(p)) setc(x, T[p].fa, p == Fa(p).c[1]);
    else T[x].fa = T[p].fa;
    setc(T[x].c[mark ^ 1], p, mark);
    setc(p, x, mark ^ 1);
    update(p), update(x);
}

void splay(int x)
{
    linkup(x);
    while (!isroot(x)) {
        int p = T[x].fa;
        if (!isroot(p)) {
            if ((x == T[p].c[1]) ^ (p == Fa(p).c[1])) rotate(x);
            else rotate(p);
        }
        rotate(x);
    }
}

void access(int x)
{
    for (register int r = 0; x; r = x, x = T[x].fa) {
        splay(x);
        T[x].c[1] = r;
        update(x);
    }
}

void makeroot(int x)
{
    access(x);
    splay(x);
    T[x].rev ^= 1;
}

void cut(int x, int y)
{
    makeroot(x), access(y), splay(y);
    T[y].c[0] = T[x].fa = 0, update(y);
}

void link(int x, int y)
{
    makeroot(x);
    T[x].fa = y;
}

int findroot(int x)
{
    access(x), splay(x);
    while (T[x].c[0]) x = T[x].c[0];
    return x;
}

int query(int x, int y)
{
    makeroot(x), access(y), splay(y);
    return T[y].mx;
}

void input()
{
    Read(n), Read(m), Read(q);
    for (register int i = 1; i <= m; i++) e[i].read();
    for (register int i = 1; i <= q; i++) {
        Read(opr[i].w), Read(opr[i].u), Read(opr[i].v);
        if (opr[i].u > opr[i].v) swap(opr[i].u, opr[i].v);
    }
}

int find(int a, int b)
{
    int l = 1, r = m, mid, re;
    while (r >= l) {
        mid = (l + r) >> 1;
        if (a == e[mid].u && b == e[mid].v) { re = mid; break; }
        else if (e[mid].u < a || (e[mid].u == a && e[mid].v < b)) l = mid + 1;
        else r = mid - 1;
    }
    return re;
}

int findfa(int x) { if (fa[x] == x) return x; else return fa[x] = findfa(fa[x]); }

void merge(int x, int y) { x = findfa(x), y = findfa(y); if (x != y) fa[x] = y; }

void prepare()
{
    int cnt = 0;
    sort(e + 1, e + m + 1, cmp);
    for (register int i = 1; i <= n; i++) fa[i] = i, val[i] = -inf;
    for (register int i = 1; i <= m; i++) e[i].id = i;
    for (register int i = 1; i <= q; i++) {
        if (opr[i].w == 2) {
            idx[i] = find(opr[i].u, opr[i].v);
            e[idx[i]].ban = true;
        }
    }
    sort(e + 1, e + m + 1);
    for (register int i = 1; i <= m; i++) {
        if (!e[i].ban) {
            int x = e[i].u, y = e[i].v, z = e[i].w;
            if (findfa(x) != findfa(y)) {
                merge(x, y);
                link(n + e[i].id, x), link(n + e[i].id, y);
                val[n + e[i].id] = z;
                cnt ++;
            }
            if (cnt == n - 1) break;
        }
    }
    sort(e + 1, e + m + 1, cmp);
}

void solve()
{
    static int ans[maxq], ln = 0;
    register int now, x, y, z, re;
    for (register int i = q; i >= 1; i--) {
        if (opr[i].w == 1) {
            ans[++ln] = val[query(opr[i].u, opr[i].v)];
        } else {
            now = idx[i], x = e[now].u, y = e[now].v, z = e[now].w, re = query(x, y);
            if (val[re] > z) {
                cut(re, e[re - n].u);
                cut(re, e[re - n].v);
                link(n + idx[i], x), link(n + idx[i], y);
                val[n + idx[i]] = z;
            }
        }
    }
    for (register int i = ln; i >= 1; i--) print(ans[i]);
}

int main()
{
    //#ifndef ONLINE_JUDGE
    freopen("tube_strong.in", "r", stdin);
    freopen("tube_strong.out", "w", stdout);
    //#endif

    input();
    prepare();
    solve();

#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;
}