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的主要内容,如果未能解决你的问题,请参考以下文章