码迷,mamicode.com
首页 > 其他好文 > 详细

Luogu4712 WC2006 水管局长 LCT

时间:2018-12-06 14:30:51      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:div   getch   clu   char   access   problem   pre   begin   root   

传送门


 

老套路,删边换成加边

然后就变成了$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\n" , ans[cntAns--]);
193     return 0;
194 }

Luogu4712 WC2006 水管局长 LCT

标签:div   getch   clu   char   access   problem   pre   begin   root   

原文地址:https://www.cnblogs.com/Itst/p/10075887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!