以MST的模板为例:
题目链接:MST模板
LCT维护MST一般是,图存在加边的动态MST,如果是删边,那么我们可以考虑使用时间倒流实现把删边变加边。但是如果是即加边又删边就不行了。
对于加边时,如果此两点没有连通,肯定是直接连接。但是如果连接了呢?,,我们就需要用当前的边来替换路径的最大值。然后我们还需要维护当前路径最大边的编号,方便cut断边。
LCT维护的点权,但是我们需要边权,所以我们可以用点来表示边。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10;
int n,m,idx,w[N],res;
int cnt,st[N];
struct node{int ch[2],fa,mx,id,re;}t[N];
inline void push_up(int p){
t[p].id=p,t[p].mx=w[p];
if(t[t[p].ch[0]].mx>t[p].mx) t[p].id=t[t[p].ch[0]].id,t[p].mx=t[t[p].ch[0]].mx;
if(t[t[p].ch[1]].mx>t[p].mx) t[p].id=t[t[p].ch[1]].id,t[p].mx=t[t[p].ch[1]].mx;
}
inline void push_re(int p){swap(t[p].ch[0],t[p].ch[1]); t[p].re^=1;}
inline void push_down(int p){
if(t[p].re){
if(t[p].ch[0]) push_re(t[p].ch[0]);
if(t[p].ch[1]) push_re(t[p].ch[1]); t[p].re^=1;
}
}
inline bool isroot(int x){return t[t[x].fa].ch[0]!=x&&t[t[x].fa].ch[1]!=x;}
inline void rotate(int x){
int y=t[x].fa,z=t[y].fa,k=t[y].ch[1]==x,w=t[x].ch[!k];
if(!isroot(y)) t[z].ch[t[z].ch[1]==y]=x; t[x].ch[!k]=y; t[y].ch[k]=w;
if(w) t[w].fa=y; t[y].fa=x; t[x].fa=z; push_up(y);
}
inline void splay(int x){
cnt=1; st[cnt]=x; int y=x;
while(!isroot(y)) st[++cnt]=y=t[y].fa;
while(cnt) push_down(st[cnt--]);
while(!isroot(x)){
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)) rotate((t[y].ch[0]==x)^(t[z].ch[0]==y)?x:y); rotate(x);
}push_up(x);
}
inline void access(int x){
for(int y=0;x;x=t[y=x].fa) splay(x),t[x].ch[1]=y,push_up(x);
}
inline void makeroot(int x){
access(x); splay(x); push_re(x);
}
inline int find(int x){
access(x); splay(x); while(t[x].ch[0]) push_down(x),x=t[x].ch[0];
splay(x); return x;
}
inline void split(int x,int y){
makeroot(x); access(y); splay(y);
}
inline void link(int x,int y){
makeroot(x); if(find(y)!=x) t[x].fa=y;
}
inline void cut(int x,int y){
makeroot(x);
if(find(y)==x&&t[y].fa==x&&!t[y].ch[0]) t[y].fa=t[x].ch[1]=0,push_up(x);
}
signed main(){
cin>>n>>m; idx=n;
for(int i=1,a,b,c;i<=m;i++){
scanf("%d %d %d",&a,&b,&c);
w[++idx]=c; makeroot(a);
if(find(b)!=a){
link(a,idx); link(idx,b); res+=c; continue;
}
split(a,b); int now=t[b].id;
if(t[now].mx<=c) continue;
res+=(c-t[now].mx),splay(now);
t[t[now].ch[0]].fa=t[t[now].ch[1]].fa=0;
link(a,idx),link(idx,b);
}
cout<<res<<endl;
return 0;
}