• 求次小生成树


    题目链接:https://cn.vjudge.net/contest/67265#problem/C

    具体思路:和判断最小生成树是否唯一的思路差不多,首先跑一遍最小生成树,在求最小生成树的过程中记录任意两个点之间的最大权值,然后试着暴力,如果有一条边没有在最小生成树上,那么就先加上这条边的权值,再去减去两个端点之间的最大权值,求一个最小值,这就是次小生成树。

    AC代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<iomanip>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<stdio.h>
    #include<algorithm>
    #include<set>
    using namespace std;
    # define ll long long
    # define inf 0x3f3f3f3f
    # define maxn 1000+100
    # define eps 1e-6
    int a[maxn][maxn];
    int used[maxn][maxn];
    int vis[maxn];
    int maxx[maxn][maxn];
    int father[maxn];
    int dis[maxn];
    int n,m;
    int mst;
    void init()
    {
        memset(vis,0,sizeof(vis));
        memset(used,0,sizeof(used));
        memset(dis,inf,sizeof(dis));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                if(i==j)
                    a[i][j]=0;
                else a[i][j]=inf;
                maxx[i][j]=0;
            }
        }
    }
    void prim()
    {
        vis[1]=1;
        dis[1]=0;
        for(int i=1; i<=n; i++)
        {
            father[i]=1;
            dis[i]=a[1][i];
        }
        father[1]=-1;
        for(int i=1; i<n; i++)
        {
            int minn=inf,index=-1;
            for(int j=1; j<=n; j++)
            {
                if(vis[j]==0&&dis[j]<minn)
                {
                    minn=dis[j];
                    index=j;
                }
            }
            if(index==-1)return ;
            vis[index]=1;
            mst+=minn;
            if(father[index]!=-1)
                used[father[index]][index]=used[index][father[index]]=1;
            for(int j=1; j<=n; j++)
            {
                if(vis[j]==0&&dis[j]>a[index][j])
                {
                    dis[j]=a[index][j];
                    father[j]=index;
                }
                else if(vis[j]&&j!=index)
                {
                    maxx[index][j]=maxx[j][index]=max(maxx[father[index]][j],dis[index]);
                }
            }
        }
    }
    int judge()
    {
        int ans=inf;
        for(int i=1; i<=n; i++)
        {
            for(int j=1+i; j<=n; j++)
            {
                if(i==j)continue;
                if(!used[i][j]&&a[i][j]!=inf)
                {
                   // cout<<i<<" "<<j<<" "<<a[i][j]<<" "<<maxx[i][j]<<endl;
                    ans=min(ans,mst+a[i][j]-maxx[i][j]);
                }
            }
        }
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            init();
            int t1,t2,t3;
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&t1,&t2,&t3);
                if(t3<a[t1][t2])
                {
                    a[t2][t1]=a[t1][t2]=t3;
                }
            }
            mst=0;
            prim();
            printf("%d",mst);
            printf(" %d
    ",judge());
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    IE安全级别没法定制
    将应用部署到Websphere的context root根/
    SqlServer插入慢的问题解决
    SqlServer中用@@IDENTITY取最新ID不准的问题
    分享我的戒烟经验
    Telnet发邮件过程
    .net垃圾回收和CLR 4.0对垃圾回收所做的改进之三
    Please pay more attention to the character set of your database
    翻旧贴: 什么是对象?
    C# Code in ASPX Page
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262828.html
Copyright © 2020-2023  润新知