zoukankan      html  css  js  c++  java
  • 20200924 次小生成树

    严格次小生成树

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define INF 1e16
    const int N=1e5+200;
    const int maxn=6*1e5+300;
    int head[maxn],edge[maxn],Next[maxn],ver[maxn],tot,fa[maxn],n,m,father[N][32],deep[N];
    long long dp[2][N][32],val1,val2,ans_max,ans;
    struct node
    {
        int x,y,z,vis;
    } s[maxn];
    int cmp(node a,node b)
    {
        return a.z<b.z;
    }
    struct Edge
    {
        void init2()
        {
            memset(head,0,sizeof(head));
            tot=0;
        }
        void add_edge(int a,int b,int c)
        {
            edge[++tot]=b;
            ver[tot]=c;
            Next[tot]=head[a];
            head[a]=tot;
        }
        int find(int x)
        {
            return x==fa[x]?x:fa[x]=find(fa[x]);
        }
        void Kruskal()
        {
            sort(s+1,s+1+m,cmp);
            for(int i=1; i<=m; i++)
            {
                int a=find(s[i].x),b=find(s[i].y);
                if (a==b)
                    continue;
                s[i].vis=1;
                fa[a]=b;
                ans+=s[i].z;
                add_edge(s[i].x,s[i].y,s[i].z);
                add_edge(s[i].y,s[i].x,s[i].z);
            }
        }
        void bfs(int root)
        {
            deep[root]=0;
            queue<int> q;
            q.push(root);
            while(q.size())
            {
                int x=q.front(),len=(int)log2(deep[x]+1);
                q.pop();
                for(int i=head[x]; i; i=Next[i])
                {
                    int y=edge[i];
                    if(y==father[x][0])
                        continue;
                    deep[y]=deep[x]+1;
                    father[y][0]=x,dp[0][y] [0]=ver[i],dp[1][y][0]=-INF;
                    q.push(y);
                    for(int t=1; t<=len; t++)
                    {
                        father[y][t]=father[father[y][t-1]][t-1];
                        if(dp[0][y][t-1]!=dp[0][father[y][t-1]][t-1])
                        {
                            dp[0][y][t]=max(dp[0][y][t-1],dp[0][father[y][t-1]][t-1]);
                            dp[1][y][t]=min(dp[0][y][t-1],dp[0][father[y][t-1]][t-1]);
                        }
                        else
    
                        {
                            dp[0][y][t]=dp[0][y][t-1];
                            dp[1][y][t]=max(dp[1][y][t-1],dp[1][father[y][t-1]][t-1]);
                        }
                    }
                }
            }
        }
        inline void update2(int x)
        {
            if(x>val1)
                val2=val1,val1=x;
            else if(x>val2 && x!=val1)
                val2=x;
        }
        inline void update(int x, int t)
        {
            update2(dp[0][x][t]);
            update2(dp[1][x][t]);
        }
        inline void Lca(int x, int y)
        {
            val1=val2=-INF;
            if(deep[x]<deep[y])
                swap(x,y);
            while(deep[x]>deep[y])
            {
                int t=(int)log2(deep[x]-deep[y]);
                update(x,t),x=father[x][t];
            }
            if(x==y)
                return;
            for(int t=(int)log2(deep[x]); t>=0; t--)
            {
                if(father[x][t]!=father[y][t])
                {
                    update(x,t),update(y,t);
                    x=father[x][t];
                    y=father[y][t];
                }
            }
            update(x,0),update(y,0);
        }
    } g1;
    int main()
    {
        scanf("%d%d",&n,&m);
        g1.init2();
        for(int i=1; i<=m; i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            s[i].x=a,s[i].y=b,s[i].z=c;
            fa[i]=i;
        }
        g1.Kruskal();
        g1.bfs(1);
        ans_max=INF;
        for(int i=1; i<=m; i++)
        {
            if(!s[i].vis)
            {
                g1.Lca(s[i].x,s[i].y);
                if(val1!=s[i].z)
                    ans_max=min(ans_max,ans-val1+s[i].z);
                else
                    ans_max=min(ans_max,ans-val2+s[i].z);
            }
        }
        printf("%lld
    ",ans_max);
        return 0;
    }
    
  • 相关阅读:
    ssh中使用spring的集成quartz 编写定时任务
    ssh只读事务的管理
    ssh2的application.xml配置文件配置详解
    spring中使用 @value 简化配置文件的读取
    【转】Spring Annotation 详解
    ssh之<context:component-scan base-package="com.xx" />
    ssh2学习-applicationContext.xml文件配置-----<context:annotation-config/>详解
    【转】线程同步------java synchronized详解
    java web程序中项目名的更改(http://localhost:8080/)后面的名字
    mysql 5.6 修改root原始密码不为空方法
  • 原文地址:https://www.cnblogs.com/scy-fisheep/p/13725233.html
Copyright © 2011-2022 走看看