LCT 最小生成树
Posted zw130-lzr-blogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCT 最小生成树相关的知识,希望对你有一定的参考价值。
闲的无聊,常数大的惊人
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #define MN 700005 #define re register int #define ll long long using namespace std; int f[MN],v[MN],s[MN],r[MN],son[MN][2]; int zhan[MN]; int n,m,cnt; int get(int x)////判断节点是否为一个Splay的根(与普通Splay的区别1) return son[f[x]][0]==x||son[f[x]][1]==x; ////如果连的是轻边,他的父亲的儿子里没有它 void pushup(int x) s[x]=x; if(v[s[x]]<v[s[son[x][0]]])s[x]=s[son[x][0]]; if(v[s[x]]<v[s[son[x][1]]])s[x]=s[son[x][1]]; void filp(int x) swap(son[x][0],son[x][1]); r[x]^=1; void pushdown(int x) if(!r[x])return; r[x]=0; if(son[x][0])filp(son[x][0]); if(son[x][1])filp(son[x][1]); void rotate(int x) int y=f[x],z=f[y],k=(son[y][1]==x),s=son[x][!k]; if(get(y))son[z][son[z][1]==y]=x;son[x][!k]=y;son[y][k]=s; if(s)f[s]=y;f[y]=x;f[x]=z; pushup(y); void splay(int x) int y=x,top=0; zhan[++top]=y; while(get(y))zhan[++top]=f[y],y=f[y]; while(top)pushdown(zhan[top--]); while(get(x)) y=f[x],top=f[y]; if(get(y)) rotate((son[y][0]==x)^(son[top][0]==y)?x:y); rotate(x); pushup(x); return; void access(int x) for(re y=0;x;y=x,x=f[x]) splay(x); son[x][1]=y; pushup(x); void makeroot(int x) access(x); splay(x); filp(x); int findroot(int x) access(x); splay(x); while(son[x][0])pushdown(x),x=son[x][0]; splay(x); return x; void split(int x,int y) makeroot(x); access(y); splay(y); void link(int x,int y) makeroot(x); if(findroot(y)!=x)f[x]=y; void cut(int x) //对cut进行%改 splay(x); f[son[x][0]]=f[son[x][1]]=0; int main() scanf("%d%d",&n,&m); int ans=0; for(re i=1;i<=m;i++) int a1,a2,a3; scanf("%d%d%d",&a1,&a2,&a3); v[i+n]=a3; makeroot(a1); if(findroot(a2)!=a1)link(a1,i+n),link(i+n,a2),ans+=a3; else split(a1,a2); int now=s[a2]; if(v[now]<=a3)continue; ans-=(v[now]-a3); cut(now); link(a1,i+n); link(i+n,a2); printf("%d\n",ans); return 0;
以上是关于LCT 最小生成树的主要内容,如果未能解决你的问题,请参考以下文章