• luogu 4234 最小差值生成树 LCT


    感觉码力严重下降~

    #include <bits/stdc++.h>  
    #define N 400006 
    #define inf 1000000000     
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    multiset<int>S;    
    multiset<int>::iterator it;         
    struct Edge 
    {
        int u,v,c; 
        Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}  
    }e[N];
    bool cmp(Edge a,Edge b) 
    {
        return a.c<b.c;    
    }   
    struct Union
    {
        int p[N];  
        void init() 
        {
            for(int i=1;i<N;++i) p[i]=i; 
        } 
        int find(int x) 
        {
            return p[x]==x?x:p[x]=find(p[x]);     
        }
        int merge(int x,int y) 
        {
            x=find(x),y=find(y); 
            if(x!=y) 
            {
                p[x]=y; 
                return 1; 
            } 
            return 0;            
        }
    }ufs;    
    struct Link_Cut_Tree
    {          
        #define lson t[x].ch[0] 
        #define rson t[x].ch[1]   
        int sta[N];     
        struct Node 
        {      
            int ch[2],f,min,id,val,rev;                          
        }t[N];   
        int isrt(int x) 
        {
            return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x);       
        }
        int get(int x)                     
        {
            return t[t[x].f].ch[1]==x; 
        }   
        void pushup(int x) 
        {     
            t[x].min=t[x].val, t[x].id=x;     
            if(lson && t[lson].min<t[x].min) t[x].min=t[lson].min,t[x].id=t[lson].id;   
            if(rson && t[rson].min<t[x].min) t[x].min=t[rson].min,t[x].id=t[rson].id;    
        } 
        void mark(int x) 
        { 
            if(x) t[x].rev^=1,swap(lson,rson);     
        }
        void pushdown(int x) 
        {   
            if(t[x].rev) 
            {
                if(lson) mark(lson); 
                if(rson) mark(rson); 
                t[x].rev=0;          
            }
        }
        void rotate(int x) 
        {
            int old=t[x].f,fold=t[old].f,which=get(x);   
            if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x;     
            t[old].ch[which]=t[x].ch[which^1], t[t[old].ch[which]].f=old;  
            t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;       
            pushup(old),pushup(x);       
        }    
        void splay(int x) 
        {
            int v=0,u=x,fa;            
            for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;      
            for(;v;--v) pushdown(sta[v]);                          
            for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) 
                if(t[fa].f!=u) 
                    rotate(get(fa)==get(x)?fa:x);          
        }
        void Access(int x) 
        {
            for(int y=0;x;y=x,x=t[x].f) 
                splay(x),rson=y,pushup(x);       
        }
        void makeroot(int x) 
        {
            Access(x),splay(x),mark(x);    
        }   
        void link(int x,int y) 
        {
            makeroot(x),t[x].f=y;      
        }   
        void cut(int x,int y) 
        {
            makeroot(x),Access(y),splay(y);   
            t[t[y].ch[0]].f=0;   
            t[y].ch[0]=0;    
            pushup(y);       
        }   
        void split(int x,int y) 
        {
            makeroot(x),Access(y),splay(y);      
        }
        #undef lson 
        #undef rson 
    }op;   
    int main() 
    { 
        int i,j,n,m,ans=inf;    
        // setIO("input");           
        scanf("%d%d",&n,&m);     
        for(i=1;i<=m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);    
        sort(e+1,e+1+m,cmp);     
        ufs.init();   
        for(i=1;i<=n;++i) op.t[i].val=inf;          
        for(i=1;i<=m;++i) 
        { 
            int x=e[i].u,y=e[i].v,c=e[i].c,_new=i+n;  
            if(x==y) continue;    
            if(ufs.merge(x,y)) 
            {    
                op.t[_new].val=c;       
                op.link(x,_new);   
                op.link(_new,y);   
                S.insert(c);       
            } 
            else
            {
                op.split(x,y);    
                if(op.t[y].min<c)                                                   
                { 
                    S.erase(S.find(op.t[y].min));       
                    S.insert(c);                                           
                    int kk=op.t[y].id;                                
                    int xx=e[kk-n].u;       
                    int yy=e[kk-n].v;       
                    op.cut(xx,kk);  
                    op.cut(yy,kk);    
                    op.t[_new].val=c;              
                    op.link(x,_new);  
                    op.link(_new,y);   
                }
            }  
            if(S.size()>=n-1) 
            {
                it=S.end();    
                it--;  
                ans=min(ans,*(it)-*(S.begin()));              
            }
        }     
        printf("%d
    ",ans);    
        return 0; 
    }
    

      

  • 相关阅读:
    linux上搭建tingproxy服务
    windows上搭建linux系统
    PHP将图片流存为图片文件
    openLayer矩形框选要素,展示要素属性
    点击选中的要素,更换标注图片,并添加文本标注
    openLayer点击要素获取对应的属性信息
    openLayer实现放大缩小
    openLayer的切换中心点、定位功能
    使用openLayer加载arcgis中的地图
    openLayer实现两个地图联动
  • 原文地址:https://www.cnblogs.com/guangheli/p/11580745.html
Copyright © 2020-2023  润新知