Luogu 2173 [ZJOI2012]网络 - LCT

Posted cychester

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu 2173 [ZJOI2012]网络 - LCT相关的知识,希望对你有一定的参考价值。

Solution

$LCT$ 直接上$QuQ$

注意$cut$ 完 需要 $d[u + c * N]--$ 再  $link$,  不然会输出Error 1的哦

 

Code

技术分享图片
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define rd read()
  5 using namespace std;
  6 
  7 const int N = 1e5 + 5;
  8 
  9 int n, m, col, Q;
 10 
 11 int read() {
 12     int X = 0, p = 1; char c = getchar();
 13     for (; c > 9 || c < 0; c = getchar())
 14         if (c == - ) p = -1;
 15     for (; c >= 0 && c <= 9; c = getchar())
 16         X = X * 10 + c - 0;
 17     return X * p;
 18 }
 19 
 20 void cmax(int &a, int b) {
 21     if (a < b)
 22         a = b;
 23 }
 24 
 25 namespace LCT {
 26     int val[N], Max[N], f[N], ch[N][2], tun[N], d[N];
 27 #define lc(x) ch[x][0]
 28 #define rc(x) ch[x][1]
 29     int isroot(int x) {
 30         return rc(f[x]) != x && lc(f[x]) != x;
 31     }
 32 
 33     int get(int x) {
 34         return rc(f[x]) == x;
 35     }
 36 
 37     void up(int x) {
 38         Max[x] = val[x];
 39         if (lc(x)) cmax(Max[x], Max[lc(x)]);
 40         if (rc(x)) cmax(Max[x], Max[rc(x)]);
 41     }
 42 
 43     void rev(int x) {
 44         swap(lc(x), rc(x));
 45         tun[x] ^= 1;
 46     }
 47 
 48     void pushdown(int x) {
 49         if (tun[x]) {
 50             if (lc(x)) rev(lc(x));
 51             if (rc(x)) rev(rc(x));
 52             tun[x] = 0;
 53         }
 54     }
 55 
 56     void pd(int x) {
 57         if (!isroot(x))
 58             pd(f[x]);
 59         pushdown(x);
 60     }
 61 
 62     void rotate(int x) {
 63         int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1];
 64         if (!isroot(old)) ch[oldf][get(old)] = x;
 65         ch[x][get(x) ^ 1] = old;
 66         ch[old][get(x)] = son;
 67         f[old] = x; f[son] = old; f[x] = oldf;
 68         up(old); up(x);
 69     }
 70 
 71     void splay(int x) {
 72         pd(x);
 73         for (; !isroot(x); rotate(x))
 74             if (!isroot(f[x]))
 75                 rotate(get(f[x]) == get(x) ? f[x] : x);
 76     }
 77 
 78     void access(int x) {
 79         for (int y = 0; x; y = x, x = f[x])
 80             splay(x), ch[x][1] = y, up(x);
 81     }
 82 
 83     void mroot(int x) {
 84         access(x); splay(x); rev(x);
 85     }
 86 
 87     int findr(int x) {
 88         access(x); splay(x);
 89         while (lc(x)) pushdown(x), x = lc(x);
 90         return x;
 91     }
 92 
 93     void split(int x, int y) {
 94         mroot(x); access(y); splay(y);
 95     }
 96     
 97     int link(int x, int y) {
 98         if (d[x] > 1 || d[y] > 1)
 99             return 1;
100         mroot(x);
101         if (findr(y) == x)
102             return 2;
103         f[x] = y;
104         return 3;
105     }
106 
107     int cut(int x, int y) {
108         mroot(x);
109         if (findr(y) != x || f[x] != y || ch[x][1])
110             return 0;
111         f[x] = ch[y][0] = 0;
112         return 1;
113     }
114 }
115 using namespace LCT;
116 
117 int main()
118 {
119     n = rd; m = rd; col = rd; Q = rd;
120     for (int i = 1; i <= n; ++i) {
121         int tmp = rd;
122         for (int j = 0; j < col; ++j)
123             val[i + j * n] = tmp;
124     }
125     for (int i = 1; i <= m; ++i) {
126         int u = rd, v = rd, z = rd;
127         link(u + z * n, v + z * n);
128         d[u + z * n]++;
129         d[v + z * n]++;
130     }
131     for (; Q; Q--) {
132         int k = rd;
133         if (k == 0) {
134             int u = rd, v = rd;
135             for (int j = 0; j < col; ++j) 
136                 mroot(u + j * n), val[u + j * n] = v, up(u + j * n);
137         }
138         if (k == 1) {
139             int u = rd, v = rd, z = rd, flag = 0, c;
140             for (int j = 0; j < col && !flag; ++j) {
141                 flag = cut(u + j * n, v + j * n);
142                 if (flag) c = j;
143             }
144             if (!flag) {puts("No such edge."); continue;}
145             d[u + c * n]--; d[v + c * n]--;
146             flag = link(u + z * n, v + z * n);
147             if (flag == 1) {
148                 puts("Error 1.");
149                 link(u + c * n, v + c * n);
150                 d[u + c * n]++; d[v + c * n]++;
151             }
152             else if (flag == 2) {
153                 puts("Error 2.");
154                 link(u + c * n, v + c * n);
155                 d[u + c * n]++; d[v + c * n]++;
156             }
157             else {
158                 puts("Success.");
159                 d[u + z * n]++; d[v + z * n]++;
160             }
161         }
162         if (k == 2) {
163             int z = rd, u = rd, v = rd;
164             u = u + z * n;
165             v = v + z * n;
166             mroot(u);
167             if (findr(v) != u) {puts("-1"); continue;}
168             printf("%d
", max(Max[lc(v)], val[v]));
169         }
170     }
171 }
View Code

 

以上是关于Luogu 2173 [ZJOI2012]网络 - LCT的主要内容,如果未能解决你的问题,请参考以下文章

luoguP2173 [ZJOI2012]网络 LCT

洛谷 2173 [ZJOI2012]网络

P2173 [ZJOI2012]网络

P2173 [ZJOI2012]网络

ZJOI2012 网络——LCT相关题目

Luogu P2597 [ZJOI2012]灾难