luoguP2173 [ZJOI2012]网络 LCT
Posted dsrdsr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP2173 [ZJOI2012]网络 LCT相关的知识,希望对你有一定的参考价值。
链接
思路
颜色很少,开10个lct分别维护
if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col) puts("Success.");continue;
这一行的代码调了半天。
代码
#include <bits/stdc++.h>
#define ls c[x][0]
#define rs c[x][1]
using namespace std;
const int N = 5e4 + 7;
int read()
int x = 0, f = 1; char s = getchar();
for (;s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1;
for (;s >= '0' && s <= '9'; s = getchar()) x = x * 10 + s - '0';
return x * f;
map<pair<int, int>, int> Hash;
int n, m, c, k, w[N];
struct LCT
int ru[N];
int f[N], c[N][2], ma[N], stak[N], lazy[N];
bool isroot(int x) return c[f[x]][0] == x || c[f[x]][1] == x;
void pushup(int x) ma[x] = max(max(ma[ls], ma[rs]), w[x]);
void tag(int x)swap(ls,rs), lazy[x] ^= 1;
void pushdown(int x)
if (lazy[x])
if (ls) tag(ls);
if (rs) tag(rs);
lazy[x] ^= 1;
void rotate(int x)
int y = f[x], z = f[y], k = c[y][1] == x, w = c[x][!k];
if (isroot(y)) c[z][c[z][1] == y] = x;
c[x][!k] = y;
c[y][k] = w;
if (w) f[w] = y;
f[x] = z;
f[y] = x;
pushup(y);
void splay(int x)
int y = x, z = 0;
stak[++z] = y;
while (isroot(y)) stak[++z] = y = f[y];
while (z) pushdown(stak[z--]);
while (isroot(x))
y = f[x], z = f[y];
if (isroot(y)) rotate((c[y][0] == x)^(c[z][0] == y) ? x : y);
rotate(x);
pushup(x);
void access(int x)
for (int y = 0; x;x = f[y = x])
splay(x), rs = y, pushup(x);
void makeroot(int x)
access(x), splay(x);
tag(x);
int findroot(int x)
access(x), splay(x);
while(ls) pushdown(x), x = ls;
return x;
void split(int x, int y)
makeroot(x), access(y), splay(y);
void link(int x, int y)
makeroot(x);
if (findroot(y) != x) f[x] = y;
void cut(int x, int y)
makeroot(x);
if (findroot(y) == x && f[x] == y && !rs)
f[x] = c[y][0] = 0;
pushup(y);
lct[11];
int main()
// freopen("a.in", "r", stdin);
int n = read(), m = read(), c = read(), k = read();
for (int i = 1; i <= n; ++i) w[i] = read();
for (int i = 1; i <= m; ++i)
int u = read(), v = read(), col = read();
Hash[make_pair(u, v)] = col;
Hash[make_pair(v, u)] = col;
lct[col].link(u, v);
lct[col].ru[u]++,lct[col].ru[v]++;
for (int i = 1; i <= k; ++i)
int opt = read();
if (opt == 0)
int x = read(), y = read();
w[x] = y;
for (int j = 0; j <= c; ++j)
lct[j].splay(x),lct[j].pushup(x);
else if (opt == 1)
int u = read(), v = read(), col = read();
if (Hash.count(make_pair(u, v)) && Hash[make_pair(u, v)] == col) puts("Success.");continue;
if (!Hash.count(make_pair(u, v))) puts("No such edge.");continue;
if (lct[col].ru[u] >= 2 || lct[col].ru[v] >= 2) puts("Error 1.");continue;
if (lct[col].findroot(u) == lct[col].findroot(v)) puts("Error 2.");continue;
int old_col = Hash[make_pair(u,v)];
Hash[make_pair(u, v)] = Hash[make_pair(v, u)] = col;
lct[old_col].ru[u]--, lct[old_col].ru[v]--;
lct[col].ru[u]++, lct[col].ru[v]++;
lct[old_col].cut(u, v);
lct[col].link(u, v);
puts("Success.");
else
int col = read(), u = read(), v = read();
if (lct[col].findroot(u) == lct[col].findroot(v))
lct[col].split(u, v);
printf("%d\n", lct[col].ma[v]);
else puts("-1");
return 0;
以上是关于luoguP2173 [ZJOI2012]网络 LCT的主要内容,如果未能解决你的问题,请参考以下文章