LCT minimum spanning tree

Idle, bored, amazing large constant

#include <the iostream> 
#include <the cmath> 
#include <CString> 
#include <cstdio> 
#include <algorithm> 
#define the MN 700005 
#define Re Register int 
#define LL Long Long 
the using namespace STD; 
int F [the MN], V [the MN], S [the MN], R & lt [the MN], Son [the MN] [2]; 
int Zhan [the MN]; 
int n-, m, CNT; 
int GET (int X) {node determines whether //// Splay a root (the difference between ordinary Splay. 1) 
    return Son [F [X]] [0] == X || Son [F [X]] [. 1] == X; 
} if connected //// a light side, his father's son there without it 
void a 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 the filp (int X) { 
    the swap (Son [X] [0], Son [X] [. 1]);  
    R & lt [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;
}

  

 

Guess you like

Origin www.cnblogs.com/zw130-lzr-blogs/p/11220319.html