zjoi网络

map加LCT水一下就过了

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <algorithm>
# include <string.h>
# include <map>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;

IL ll Read(){
    RG char c = getchar(); RG ll x = 0, z = 1;
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
    return x * z;
}

const int MAXN(10010);
int n, m, C, K, w[MAXN], S[MAXN];
struct Edge{
    int u, v;
    IL bool operator <(RG Edge B) const{  return u == B.u ? v < B.v : u < B.u;  }
};
map <Edge, int> M;
struct Tree{  int ch[2], rev, fa, max, cnt;  } t[11][MAXN];

IL bool Son(RG int x){  return t[C][t[C][x].fa].ch[1] == x;  }

IL bool Isroot(RG int x){  return t[C][t[C][x].fa].ch[0] != x && t[C][t[C][x].fa].ch[1] != x;  }

IL void Update(RG int x){  t[C][x].max = max(w[x], max(t[C][t[C][x].ch[0]].max, t[C][t[C][x].ch[1]].max));  }

IL void Pushdown(RG int x){
    if(!t[C][x].rev) return; t[C][x].rev = 0;
    swap(t[C][x].ch[0], t[C][x].ch[1]);
    t[C][t[C][x].ch[0]].rev ^= 1; t[C][t[C][x].ch[1]].rev ^= 1;
}

IL void Rot(RG int x){
    RG int y = t[C][x].fa, z = t[C][y].fa, c = Son(x);
    if(!Isroot(y)) t[C][z].ch[Son(y)] = x; t[C][x].fa = z;
    t[C][y].ch[c] = t[C][x].ch[!c]; t[C][t[C][y].ch[c]].fa = y;
    t[C][x].ch[!c] = y; t[C][y].fa = x;
    Update(y);
}

IL void Splay(RG int x){
    RG int top = 0; S[++top] = x;
    for(RG int y = x; !Isroot(y); y = t[C][y].fa) S[++top] = t[C][y].fa;
    while(top) Pushdown(S[top--]);
    for(RG int y = t[C][x].fa; !Isroot(x); Rot(x), y = t[C][x].fa)
        if(!Isroot(y)) Son(y) ^ Son(x) ? Rot(x) : Rot(y);
    Update(x);
}

IL void Access(RG int x){  for(RG int y = 0; x; y = x, x = t[C][x].fa) Splay(x), t[C][x].ch[1] = y, Update(x);  }

IL int Findroot(RG int x){  Access(x); Splay(x); while(t[C][x].ch[0]) x = t[C][x].ch[0]; return x;  }

IL void Makeroot(RG int x){  Access(x); Splay(x); t[C][x].rev ^= 1;  }

IL void Split(RG int x, RG int y){  Makeroot(x); Access(y); Splay(y);  }

IL void Link(RG int x, RG int y){  t[C][x].cnt++; t[C][y].cnt++; Makeroot(x); t[C][x].fa = y;  }

IL void Cut(RG int x, RG int y){  Split(x, y); t[C][x].cnt--; t[C][y].cnt--; t[C][x].fa = t[C][y].ch[0] = 0;  }

IL int Query(RG int x, RG int y){  Split(x, y); return t[C][y].max;  }

int main(RG int argc, RG char* argv[]){
    n = Read(); m = Read(); C = Read(); K = Read(); RG int Col = C;
    for(RG int i = 1; i <= n; i++) w[i] = Read();
    for(RG int i = 1; i <= m; i++){
        RG int u = Read(), v = Read(); C = Read() + 1;
        M[(Edge){u, v}] = M[(Edge){v, u}] = C; Link(u, v);
    }
    while(K--){
        RG int opt = Read(), x = Read(), y = Read(), z, zz;
        if(!opt){  w[x] = y; for(C = 1; C <= Col; C++) Splay(x);  }
        else if(opt == 1){
            z = Read() + 1; C = zz = M[(Edge){x, y}];
            if(!C){  puts("No such edge."); continue;  }
            if(C == z){  puts("Success."); continue;  }
            if(t[z][x].cnt > 1 || t[z][y].cnt > 1){  puts("Error 1."); continue;  }
            C = z; if(Findroot(x) == Findroot(y)){  puts("Error 2."); continue;  }
            C = zz; Cut(x, y); C = z; Link(x, y); M[(Edge){x, y}] = M[(Edge){y, x}] = C; puts("Success.");
        }
        else{
            C = x + 1; x = Read();
            if(Findroot(x) != Findroot(y)) puts("-1");
            else printf("%d
", Query(x, y));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cjoieryl/p/8206380.html