• 严格次小生成树[BJWC2010]


    题目

    维护环内最大值与严格次大值

    与未放入最小生成树的边枚举加入

    #include<bits/stdc++.h>
    #define re return
    #define dec(i,l,r) for(ll i=l;i>=r;--i)
    #define inc(i,l,r) for(ll i=l;i<=r;++i)
    
    typedef long long ll;
    
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    const int maxn=100005,maxm=300005;
    ll n,m,k=1,hd[maxn],deep[maxn];
    ll max1[maxn][21],max2[maxn][21],fa[maxn][21];
    ll vis[maxm],f[maxn];
    ll sum,ans=999999999999999999;
    
    struct node
    {
        ll fr,to,nt,val;
        bool operator<(node p)const 
        {
            re val<p.val;
        }
    }e[maxm],e1[maxn<<1];
    
    inline void add1(int x,int y,int z)
    {
        e1[++k].to=y;e1[k].nt=hd[x];hd[x]=k;e1[k].val=z;
        e1[++k].to=x;e1[k].nt=hd[y];hd[y]=k;e1[k].val=z;
    }    
    
    
    inline void dfs(int x)
    {
        deep[x]=deep[fa[x][0]]+1;
        for(int i=0;fa[fa[x][i]][i];++i)
        {
            fa[x][i+1]=fa[fa[x][i]][i];
            if(max1[x][i]==max1[fa[x][i]][i])
            {
                max1[x][i+1]=max1[x][i];
                max2[x][i+1]=max(max2[x][i],max2[fa[x][i]][i]);
            }
            else if(max1[x][i]>max1[fa[x][i]][i])
            {
                max1[x][i+1]=max1[x][i];
                max2[x][i+1]=max(max1[fa[x][i]][i],max2[x][i]);
            }
            else 
            {
                max1[x][i+1]=max1[fa[x][i]][i];
                max2[x][i+1]=max(max1[x][i],max2[fa[x][i]][i]);
            }    
        } 
        
        for(ll i=hd[x];i;i=e1[i].nt)
        {
            ll v=e1[i].to;
            if(v==fa[x][0])continue;
            fa[v][0]=x;
            max1[v][0]=e1[i].val;
            max2[v][0]=-2147483647;
            dfs(v);
        }
    }
    
    
    inline ll find(ll x)
    {
        re x==f[x]?x:f[x]=find(f[x]);
    }
    int main()
    {
        
    //    freopen("in.txt","r",stdin);
    freopen("tree8.in","r",stdin);
        
        ll x,y,z; 
        
        rd(n),rd(m);
        inc(i,1,n)f[i]=i;
        
        inc(i,1,m)
        {
            rd(x),rd(y),rd(z);
            e[i]=(node){x,y,0,z};
        }
        
        sort(e+1,e+m+1);
        
        k=0;
        ll cnt=0;
        inc(i,1,m)
        {
            x=find(e[i].to),y=find(e[i].fr);
            if(x!=y)
            {
                add1(e[i].to,e[i].fr,e[i].val);
                sum+=e[i].val; 
                vis[i]=1;
                f[x]=y;
                ++cnt;
                if(cnt==n-1)break;
            }
        }
        
        dfs(1);
        
        inc(j,1,m)
        if(!vis[j])
        {
            x=e[j].to;y=e[j].fr;
    //--------------------------------------------------------------------------------        
            ll d1=0,d2=0;
            if(deep[x]<deep[y])swap(x,y);
            
            dec(i,20,0)
            if(deep[fa[x][i]]>=deep[y])
            {
                if(max1[x][i]>d1)
                {
                    d2=max(d1,max2[x][i]);
                    d1=max1[x][i];
                }
                else if(max1[x][i]!=d1)
                     d2=max(d2,max1[x][i]);
                
                x=fa[x][i];
            }
            if(x!=y)
            {
                dec(i,20,0)
                if(fa[x][i]!=fa[y][i])
                {
                    if(max1[x][i]>d1)
                    {
                        d2=max(d1,max2[x][i]);
                        d1=max1[x][i];
                    }
                    else if(max1[x][i]!=d1)
                         d2=max(d2,max1[x][i]);
                         
                    if(max1[y][i]>d1)
                    {
                        d2=max(d1,max2[y][i]);
                        d1=max1[y][i];
                    }
                    else if(max1[y][i]!=d1)
                         d2=max(d2,max1[y][i]);
                    x=fa[x][i];y=fa[y][i];
                }
                if(max1[x][0]>d1)
                {
                    d2=d1;
                    d1=max1[x][0]; 
                } 
                else if(max1[x][0]!=d1)
                    d2=max(d2,max1[x][0]);
                if(max1[y][0]>d1)
                {
                    d2=d1;
                    d1=max1[y][0]; 
                } 
                else if(max1[y][0]!=d1)
                    d2=max(d2,max1[y][0]);
                
            } 
    //-----------------------------------------------------------------------------------------------------        
            if(d1==e[j].val)ans=min(ans,sum+e[j].val-d2);
            else ans=min(ans,sum+e[j].val-d1);
        }
        
        printf("%lld",ans); 
        re 0;
    }
  • 相关阅读:
    paip.解决Invalid byte 2 of 2byte UTF8 sequence.
    poj1157
    poj1258
    poj1160
    poj1113
    poj1159
    !!!GRETA正则表达式模板类库
    【原创】C#与C++的混合编程采用其中的第三种方法
    WinApi.cs
    C#:正则表达式30分钟入门教程
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11417366.html
Copyright © 2020-2023  润新知