• 洛谷 P4180 【模板】严格次小生成树[BJWC2010] LCT


    首次采用了压行,感觉还不错。

    Code:

    // luogu-judger-enable-o2
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    using namespace std;
    void setIO(string a){
        freopen((a+".in").c_str(),"r",stdin);
        //freopen((a+".out").c_str(),"w",stdout);
    }
    #define inf 1000000000
    #define maxn 300007
    int ch[maxn][2],f[maxn],val[maxn],max1[maxn],max2[maxn];
    int sta[maxn],tag[maxn];
    int lson(int x){ return ch[x][0]; }
    int rson(int x){ return ch[x][1]; }
    int get(int x){ return ch[f[x]][1]==x; }
    int isRoot(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
    void mark(int x){ if(x) swap(ch[x][0],ch[x][1]),tag[x]^=1; }
    void pushdown(int x){ if(tag[x]) mark(lson(x)), mark(rson(x)), tag[x]=0; }
    void pushup(int x){
        if(max1[lson(x)]>max1[rson(x)]) max1[x]=max1[lson(x)], max2[x]=max(max2[lson(x)],max1[rson(x)]);
        else if(max1[lson(x)]<max1[rson(x)]) max1[x]=max1[rson(x)], max2[x]=max(max2[rson(x)],max1[lson(x)]);
        else max1[x]=max1[lson(x)], max2[x]=max(max2[lson(x)],max2[rson(x)]);
    
        if(val[x]>max1[x]) max2[x]=max1[x],max1[x]=val[x];
        else if(val[x]!=max1[x]) max2[x]=max(max2[x],val[x]);
    }
    
    void rotate(int x) {
        int old=f[x],oldf=f[old],which=get(x);
        if(!isRoot(old)) ch[oldf][ch[oldf][1]==old]=x;
        ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
        ch[x][which^1]=old,f[old]=x,f[x]=oldf;
        pushup(old),pushup(x);
    }
    
    void splay(int x){
        int v=0,u=x;
        sta[++v]=u; 
        while(!isRoot(u)) sta[++v]=f[u],u=f[u];
        while(v) pushdown(sta[v--]);
        u=f[u];
        for(int fa;(fa=f[x])!=u;rotate(x))
            if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
    }
    
    void Access(int x){ for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,pushup(x); }
    void makeRoot(int x){ Access(x),splay(x),mark(x); }
    void split(int x,int y){ makeRoot(x),Access(y),splay(y); }
    struct Union_Find{
        int p[maxn];
        int find(int x){ return p[x]==x?x:p[x]=find(p[x]);}
        void init(){for(int i=1;i<maxn;++i)p[i]=i;}
        void merge(int x,int y){ int a=find(x),b=find(y); if(a!=b) p[a]=b; }
    }tree;
    struct Edge{
        int u,v,c;
        Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}
    }edges[maxn];
    bool cmp(Edge e1,Edge e2){ return e1.c<e2.c; }
    int main(){   
        //setIO("input");
        tree.init();
        int n,m,cnt,x,y,ans=inf;
        long long sum=0;
        scanf("%d%d",&n,&m),cnt=n;
        for(int i=1;i<=m;++i) scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].c);
        sort(edges+1,edges+1+m,cmp);
        for(int i=1;i<=m;++i){
            x=edges[i].u,y=edges[i].v;
            if(tree.find(x)==tree.find(y)){
                split(x,y);
                ans=min(ans,edges[i].c-(max1[y]>=edges[i].c?max2[y]:max1[y])); 
            }
            else{
                makeRoot(x);
                f[f[x]=++cnt]=y;
                max1[cnt]=val[cnt]=edges[i].c;
                sum+=edges[i].c;
                tree.merge(x,y);
            }
        }
        printf("%lld",sum+ans);
        return 0;
    }
    

      

  • 相关阅读:
    将base64格式的字符串生成文件
    断点继传
    判断文件后缀
    递归遍历指定目录,获取该目录下最大的文件信息
    web项目部署后动态编译无法找到依赖的jar包
    Java程序动态编译Java源文件
    JS中substr与substring的区别
    java.lang.NoClassDefFoundError: com/sun/tools/javac/processing/JavacProcessingEnvironment
    python 基础学习笔记(4)--字典 和 集合
    python 基础学习笔记(3)--列表与元组
  • 原文地址:https://www.cnblogs.com/guangheli/p/10083064.html
Copyright © 2020-2023  润新知