zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        return 0;
    }
    

      

    缘分让我们相遇乱世以外, 命运却要我们危难中相爱。 也许未来遥远在光年之外, 我愿守候未知里为你等待。
  • 相关阅读:
    ubuntu基本配置学习(1)
    UITabBarController使用详解
    Could not find a storyboard named 'Main' in bundle NSBundle </Users/tianxiao/
    检查更新功能
    SDWebImage手动清除缓存的方法
    错误记录1
    如何获取path路径
    iOS如何获得本地Documents下的文件夹名称或文件名称
    重头系统的学习,不会咱就学!2014.6.18
    错误1
  • 原文地址:https://www.cnblogs.com/zw130-lzr-blogs/p/11220319.html
Copyright © 2011-2022 走看看