1. 程式人生 > >[ZJOI 2012] 網絡

[ZJOI 2012] 網絡

++ roo emp esp template clas char getc cte

[題目鏈接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2816

[算法]

對每種顏色的邊建一棵LCT , 維護聯通性即可

時間復雜度 : O(C * NlogN ^ 2)

[代碼]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
const int MAXC = 15;
typedef long long ll;
typedef long double ld;
typedef unsigned 
long long ull; int n , m , c , k; int u[MAXN] , v[MAXN] , w[MAXN] , val[MAXN] , cnt[MAXC][MAXN]; map< pair<int , int> , int> mp; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template
<typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0; x *= f; } struct Link_Cut_Tree { struct Node {
int father , son[2] , value , mx; bool tag; } a[MAXN]; inline void init() { for (int i = 1; i <= n; i++) { a[i].father = 0; a[i].son[0] = a[i].son[1] = 0; a[i].value = a[i].mx = val[i]; a[i].tag = false; } } inline void pushdown(int x) { if (a[x].tag) { swap(a[x].son[0] , a[x].son[1]); a[a[x].son[0]].tag ^= 1; a[a[x].son[1]].tag ^= 1; a[x].tag = false; } } inline void update(int x) { a[x].mx = a[x].value; if (a[x].son[0]) chkmax(a[x].mx , a[a[x].son[0]].mx); if (a[x].son[1]) chkmax(a[x].mx , a[a[x].son[1]].mx); } inline bool get(int x) { pushdown(x); return a[a[x].father].son[1] == x; } inline bool nroot(int x) { return a[a[x].father].son[0] == x || a[a[x].father].son[1] == x; } inline void rotate(int x) { int f = a[x].father , g = a[f].father; int tmpx = get(x) , tmpf = get(f); int w = a[x].son[tmpx ^ 1]; if (nroot(f)) a[g].son[tmpf] = x; a[x].son[tmpx ^ 1] = f; a[f].son[tmpx] = w; if (w) a[w].father = f; a[f].father = x; a[x].father = g; update(f); } inline void splay(int x) { int y = x , z = 0; static int st[MAXN]; st[++z] = y; while (nroot(y)) st[++z] = y = a[y].father; while (z) pushdown(st[z--]); while (nroot(x)) { int y = a[x].father , z = a[y].father; if (nroot(y)) rotate((a[z].son[0] == y) ^ (a[y].son[0] == x) ? x : y); rotate(x); } update(x); } inline void access(int x) { for (int y = 0; x; x = a[y = x].father) { splay(x); a[x].son[1] = y; update(x); } } inline void make_root(int x) { access(x); splay(x); a[x].tag ^= 1; pushdown(x); } inline void link(int x , int y) { make_root(x); if (find_root(y) != x) a[x].father = y; } inline int find_root(int x) { access(x); splay(x); while (a[x].son[0]) { pushdown(x); x = a[x].son[0]; } return x; } inline void cut(int x , int y) { make_root(x); if (find_root(y) == x && a[x].father == y && !a[x].son[1]) { a[x].father = a[y].son[0] = 0; update(y); } } inline void split(int x , int y) { make_root(x); access(y); splay(y); } inline void modify(int x , int y) { splay(x); a[x].value = y; update(x); } inline bool connected(int x , int y) { return (find_root(x) == find_root(y)); } inline int query(int x , int y) { split(x , y); return a[y].mx; } } T[MAXC]; int main() { read(n); read(m); read(c); read(k); for (int i = 1; i <= n; i++) read(val[i]); for (int i = 0; i < c; i++) T[i].init(); for (int i = 1; i <= m; i++) { read(u[i]); read(v[i]); read(w[i]); mp[make_pair(u[i] , v[i])] = mp[make_pair(v[i] , u[i])] = w[i]; T[w[i]].link(u[i] , v[i]); ++cnt[w[i]][u[i]]; ++cnt[w[i]][v[i]]; } for (int i = 1; i <= k; i++) { int type; read(type); if (type == 0) { int x , y; read(x); read(y); for (int i = 0; i < c; i++) T[i].modify(x , y); } else if (type == 1) { int u , v , w; read(u); read(v); read(w); if (!mp.count(make_pair(u , v))) { printf("No such edge.\n"); continue; } else { int value = mp[make_pair(u , v)]; if (value == w) { printf("Success.\n"); continue; } if (cnt[w][u] >= 2 || cnt[w][v] >= 2) { printf("Error 1.\n"); continue; } if (T[w].connected(u , v)) { printf("Error 2.\n"); continue; } printf("Success.\n"); T[value].cut(u , v); --cnt[value][u]; --cnt[value][v]; T[w].link(u , v); mp[make_pair(u , v)] = mp[make_pair(v , u)] = w; ++cnt[w][u]; ++cnt[w][v]; } } else { int w , u , v; read(w); read(u); read(v); if (!T[w].connected(u , v)) printf("-1\n"); else printf("%d\n" , T[w].query(u , v)); } } return 0; }

[ZJOI 2012] 網絡