Luogu4712 WC2006 水管局长 LCT

Posted itst

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu4712 WC2006 水管局长 LCT相关的知识,希望对你有一定的参考价值。

传送门


 

老套路,删边换成加边

然后就变成了$LCT$维护最小生成树的裸题

化边为点,对于每一个点记录链上最大值和对应的边的编号,每一次加入一条边时考虑是否能通过割掉当前树上路径上的最大权值的边获得一个更小的生成树。

  1 #include<bits/stdc++.h>
  2 //This code is written by Itst
  3 using namespace std;
  4 
  5 inline int read(){
  6     int a = 0;
  7     bool f = 0;
  8     char c = getchar();
  9     while(c != EOF && !isdigit(c)){
 10         if(c == -)
 11             f = 1;
 12         c = getchar();
 13     }
 14     while(c != EOF && isdigit(c)){
 15         a = (a << 3) + (a << 1) + (c ^ 0);
 16         c = getchar();
 17     }
 18     return f ? -a : a;
 19 }
 20 
 21 const int MAXN = 100010;
 22 vector < pair < int , int > > del[MAXN] , bef[MAXN] , Edge;
 23 struct query{
 24     int type , s , t , w;
 25 }now[MAXN];
 26 struct node{
 27     int ch[2] , fa , maxInd , val;
 28     bool mark;
 29 }Tree[MAXN * 11];
 30 int N , M , Q , cnt , ans[MAXN] , cntAns;
 31 
 32 inline bool nroot(int x){
 33     return Tree[Tree[x].fa].ch[0] == x || Tree[Tree[x].fa].ch[1] == x;
 34 }
 35 
 36 inline bool son(int x){
 37     return Tree[Tree[x].fa].ch[1] == x;
 38 }
 39 
 40 inline int cmp(int a , int b){
 41     return Tree[a].val > Tree[b].val ? a : b;
 42 }
 43 
 44 inline void pushup(int x){
 45     Tree[x].maxInd = cmp(x , cmp(Tree[Tree[x].ch[0]].maxInd , Tree[Tree[x].ch[1]].maxInd));
 46 }
 47 
 48 inline void ZigZag(int x){
 49     bool f = son(x);
 50     int y = Tree[x].fa , z = Tree[y].fa , w = Tree[x].ch[f ^ 1];
 51     if(nroot(y))
 52         Tree[z].ch[son(y)] = x;
 53     Tree[x].fa = z;
 54     Tree[x].ch[f ^ 1] = y;
 55     Tree[y].fa = x;
 56     Tree[y].ch[f] = w;
 57     if(w)
 58         Tree[w].fa = y;
 59     pushup(y);
 60     pushup(x);
 61 }
 62 
 63 inline void pushdown(int x){
 64     if(Tree[x].mark){
 65         Tree[Tree[x].ch[0]].mark ^= 1;
 66         Tree[Tree[x].ch[1]].mark ^= 1;
 67         Tree[x].mark = 0;
 68         swap(Tree[x].ch[0] , Tree[x].ch[1]);
 69     }
 70 }
 71 
 72 void pushdown_all(int x){
 73     if(nroot(x))
 74         pushdown_all(Tree[x].fa);
 75     pushdown(x);
 76 }
 77 
 78 inline void Splay(int x){
 79     pushdown_all(x);
 80     while(nroot(x)){
 81         if(nroot(Tree[x].fa))
 82             ZigZag(son(x) == son(Tree[x].fa) ? Tree[x].fa : x);
 83         ZigZag(x);
 84     }
 85 }
 86 
 87 inline void access(int x){
 88     for(int y = 0 ; x ; y = x , x = Tree[x].fa){
 89         Splay(x);
 90         Tree[x].ch[1] = y;
 91         pushup(x);
 92     }
 93 }
 94 
 95 inline int findroot(int x){
 96     access(x);
 97     Splay(x);
 98     pushdown(x);
 99     while(Tree[x].ch[0])
100         pushdown(x = Tree[x].ch[0]);
101     Splay(x);
102     return x;
103 }
104 
105 inline void makeroot(int x){
106     access(x);
107     Splay(x);
108     Tree[x].mark ^= 1;
109 }
110 
111 inline void split(int x , int y){
112     makeroot(x);
113     access(y);
114     Splay(y);
115 }
116 
117 inline void _link(int x , int y){
118     makeroot(x);
119     Tree[x].fa = y;
120 }
121 
122 inline void cut(int x , int y){
123     split(x , y);
124     Tree[x].fa = Tree[y].ch[0] = 0;
125     pushup(y);
126 }
127 
128 inline void link(int x , int y , int tar){
129     if(findroot(x) == findroot(y)){
130         split(x , y);
131         if(Tree[Tree[y].maxInd].val <= Tree[tar].val)
132             return;
133         int t = Tree[y].maxInd;
134         cut(t , Edge[t - N].first);
135         cut(t , Edge[t - N].second);
136     }
137     _link(x , tar);
138     _link(y , tar);
139 }
140 
141 int main(){
142 #ifndef ONLINE_JUDGE
143     freopen("4172.in" , "r" , stdin);
144     freopen("4172.out" , "w" , stdout);
145 #endif
146     cnt = N = read();
147     M = read();
148     Q = read();
149     for(int i = 1 ; i <= M ; ++i){
150         int a = read() , b = read() , c = read();
151         if(a > b)
152             swap(a , b);
153         bef[a].push_back(make_pair(b , c));
154     }
155     for(int i = 1 ; i <= N ; ++i)
156         sort(bef[i].begin() , bef[i].end());
157     for(int i = 1 ; i <= Q ; ++i){
158         now[i].type = read();
159         now[i].s = read();
160         now[i].t = read();
161         if(now[i].s > now[i].t)
162             swap(now[i].s , now[i].t);
163         if(now[i].type == 2)
164             del[now[i].s].push_back(make_pair(now[i].t , i));
165     }
166     Edge.push_back(make_pair(0 , 0));
167     for(int i = 1 ; i <= N ; ++i){
168         sort(del[i].begin() , del[i].end());
169         int p = 0 , k = del[i].size() , q = bef[i].size();
170         for(int j = 0 ; j < q ; ++j)
171             if(p < k && del[i][p].first == bef[i][j].first)
172                 now[del[i][p++].second].w = bef[i][j].second;
173             else{
174                 Edge.push_back(make_pair(i , bef[i][j].first));
175                 Tree[++cnt].val = bef[i][j].second;
176                 Tree[cnt].maxInd = cnt;
177                 link(i , bef[i][j].first , cnt);
178             }
179     }
180     for(int i = Q ; i ; --i)
181         if(now[i].type == 2){
182             Edge.push_back(make_pair(now[i].s , now[i].t));
183             Tree[++cnt].val = now[i].w;
184             Tree[cnt].maxInd = cnt;
185             link(now[i].s , now[i].t , cnt);
186         }
187         else{
188             split(now[i].s , now[i].t);
189             ans[++cntAns] = Tree[Tree[now[i].t].maxInd].val;
190         }
191     while(cntAns)
192         printf("%d
" , ans[cntAns--]);
193     return 0;
194 }

以上是关于Luogu4712 WC2006 水管局长 LCT的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P4172 [WC2006]水管局长

Luogu P4172 [WC2006]水管局长

BZOJ_2594_[Wc2006]水管局长数据加强版_LCT

[WC2006]水管局长(LCT)

BZOJ2594 [Wc2006]水管局长数据加强版LCT

luoguP4172 [WC2006]水管局长