码迷,mamicode.com
首页 > 其他好文 > 详细

[模板] 严格次小生成树

时间:2018-08-25 21:18:18      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:for   bool   最小   min   href   void   eof   +=   long   

题目链接

先求当前图中的最小生成树,再将没有选的边一一安放(放完一个就卸下),这样每次就形成一个环,再求这个环除了它以外的最短权值,这样就会想到lca,因为树的路径是唯一的,并且时间也不会超时,再将原答案加上这条边的权值减去最大的环上权值的最小值即为答案

调了一下午,哎~,板子打WA了,一个1<<i被我写成了i<<1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline long long read()
{
    long long f=1,ans=0;char c;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){ans=ans*10+c-0;c=getchar();}
    return ans*f;
}
long long n,m,f[100001];
struct node1{
    long long u,v,w;
}x[600001];
bool cmp(node1 x1,node1 x2)
{
    return x1.w<x2.w;
 } 
long long find(long long x)
{
    if(f[x]==x) return x;
    return f[x]=find(f[x]);
}
struct node{
    long long u,v,w;
}xx[600001];
struct node3{
    long long u,v,w,nex;
}s[600001];
long long cntt;
long long cnt;
long long ans;
long long head[100001];
long long maxn1[100001][18],maxn2[100001][18],fa[100001][18],deep[100001];
long long data=0x3f3f3f3f3f3f3f3f;
void add(long long u,long long v,long long w)
{
    s[cntt].u=u,s[cntt].v=v,s[cntt].w=w,s[cntt].nex=head[u],head[u]=cntt++;
}
void dfs(long long f,long long fath)
{
    deep[f]=deep[fath]+1;
    fa[f][0]=fath;
    for(long long i=1;(1<<i)<=deep[f];i++)
    {
        fa[f][i]=fa[fa[f][i-1]][i-1];
        maxn1[f][i]=max(maxn1[f][i-1],maxn1[fa[f][i-1]][i-1]);
        if(maxn1[f][i-1]==maxn1[fa[f][i-1]][i-1]) maxn2[f][i]=max(maxn2[f][i-1],maxn2[fa[f][i-1]][i-1]);
        else maxn2[f][i]=max(min(maxn1[f][i-1],maxn1[fa[f][i-1]][i-1]),max(maxn2[f][i-1],maxn2[fa[f][i-1]][i-1]));
    }
    for(long long i=head[f];i!=-1;i=s[i].nex)
    {
        if(s[i].v==fath) continue;
        maxn1[s[i].v][0]=s[i].w;
        dfs(s[i].v,f); 
    }
}
void kcal()
{
    memset(head,-1,sizeof(head));
    n=read(),m=read();
    for(long long i=1;i<=n;i++) f[i]=i;
    for(long long i=1;i<=m;i++) x[i].u=read(),x[i].v=read(),x[i].w=read(); 
    sort(x+1,x+m+1,cmp);
    for(long long i=1;i<=m;i++)
    {
        long long t1=find(x[i].u),t2=find(x[i].v);
        if(t1!=t2)
        {
            f[t2]=t1;
            ans+=x[i].w;
            add(x[i].u,x[i].v,x[i].w),add(x[i].v,x[i].u,x[i].w);
        }
        else xx[++cnt].u=x[i].u,xx[cnt].v=x[i].v,xx[cnt].w=x[i].w;
    }
}
long long lca(long long u,long long v,long long w)
{
    long long dis1=-1,dis2=-1;
    if(deep[u]<deep[v]) swap(u,v);
    for(long long i=17;i>=0;i--)
    {
        if(deep[u]-(1<<i)>=deep[v]) 
        {    
            dis2=max(dis2,maxn2[u][i]);
            if(maxn1[u][i]>dis1) dis2=max(dis1,max(dis2,maxn2[u][i])),dis1=maxn1[u][i];
            else dis2=max(dis2,maxn1[u][i]);
            u=fa[u][i];
        }
    }
    if(u==v) 
    {
        if(dis1==w) return dis2;
        return dis1;
    }
    for(long long i=17;i>=0;i--)
    {
        
        if(fa[u][i]==fa[v][i]) continue;
        dis2=max(dis2,maxn2[u][i]);
        if(maxn1[u][i]>dis1) dis2=max(dis1,max(dis2,maxn2[u][i])),dis1=maxn1[u][i];
        else dis2=max(dis2,maxn1[u][i]);
        u=fa[u][i];
        dis2=max(dis2,maxn2[v][i]);
        if(maxn1[v][i]>dis1) dis2=max(dis1,max(dis2,maxn2[v][i])),dis1=maxn1[v][i];
        else dis2=max(dis2,maxn1[v][i]);
        v=fa[v][i];
    }
    dis2=max(dis2,maxn2[u][0]);
    if(maxn1[u][0]>dis1) dis2=max(dis1,max(dis2,maxn2[u][0])),dis1=maxn1[u][0];
    else dis2=max(dis2,maxn1[u][0]);
    u=fa[u][0];
    dis2=max(dis2,maxn2[v][0]);
    if(maxn1[v][0]>dis1) dis2=max(dis1,max(dis2,maxn2[v][0])),dis1=maxn1[v][0];
    else dis2=max(dis2,maxn1[v][0]);
    v=fa[v][0];
    if(dis1==w) return dis2;
    return dis1;
}
int main()
{
    kcal();
    dfs(1,0);
    for(long long i=1;i<=cnt;i++) data=min(data,ans+xx[i].w-lca(xx[i].u,xx[i].v,xx[i].w));
    if(ans!=data)cout<<data;
    else cout<<data+1;
}

 

[模板] 严格次小生成树

标签:for   bool   最小   min   href   void   eof   +=   long   

原文地址:https://www.cnblogs.com/si-rui-yang/p/9535192.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!