1. 程式人生 > >Luogu4712 WC2006 水管局長 LCT

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\n" , ans[cntAns--]); 193 return 0; 194 }