• poj 1679(次小生成树)


    题意:有n个点,m个遍的无向图,问是否存在唯一最小生成树,存在则输出最小生成树边权和。否则输出Not Unique!

    思路:当然首先判断是否构成生成树,然后用次小生成树和最小生成树比较,如果相等则就不唯一了。否则唯一。

    (这里说的次小生成树是非严格的次小生成树  Σw次≥Σw最小

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    using namespace std;
    const int maxn=110;
    bool visit[maxn];
    int Map[maxn][maxn];
    bool used[maxn][maxn];//两个点的那条边是否被使用过;
    int Max[maxn][maxn];//记录MST中两个点的最大距离;
    int dist[maxn];
    int pre[maxn];//保存父节点;
    int n,m,ans;
    int prime()//求最小生成树 
    {
        ans=0;
        memset(visit,false,sizeof(visit));
        memset(Max,0,sizeof(Max));
        memset(used,0,sizeof(used));
        visit[1]=1;
        pre[1]=-1;
        for(int i=2;i<=n;i++)
        {
            dist[i]=Map[1][i];
            pre[i]=1;
        }
        dist[1]=0;
        for(int i=1;i<=n-1;i++)
        {
            int lowcast=inf;
            int temp=-1;
            for(int j=1;j<=n;j++)
            {
                if(!visit[j]&&lowcast>dist[j])
                {
                    lowcast=dist[j];
                    temp=j;
                }
            }
            if(lowcast==inf)//这说明有点不连通;
                return -1;
            ans+=lowcast;//最小生成树的值;
            visit[temp]=1;
            used[temp][pre[temp]]=used[pre[temp]][temp]=1;
            for(int j=1;j<=n;j++)
            {
                if(visit[j])
                    Max[j][temp]=Max[temp][j]=max(Max[j][pre[temp]],dist[temp]);//数组的作用是记录MST里面两个点的最大距离;
                if(!visit[j]&&dist[j]>Map[temp][j])
                {
                    dist[j]=Map[temp][j];
                    pre[j]=temp;
                }
            }
        }
        return ans;
    }
    int SMST()
    {
        int minn=inf;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(Map[i][j]!=inf&&(!used[i][j]))
                {
                    minn=min(minn,ans+Map[i][j]-Max[i][j]);
                }
            }
        }
        if(minn==inf)
            return -1;//没有次小生成树;
        return minn;
    }
    int main()
    {
        int t;
        int x,y,w;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
               for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i==j)  Map[i][j]=0;
                else Map[i][j]=inf;
            for(int i=1;i<=m;i++)
            {
                cin>>x>>y>>w;
                Map[x][y]=Map[y][x]=w;
            }
                int ans=prime();
                if(ans==-1)
               {
               printf("Not Unique!
    ");
               continue;
            }
                if(ans==SMST())
                printf("Not Unique!
    ");//最小生成树和次小生成树相等 
            else 
                printf("%d
    ",ans);
        }
       return 0;
    }
  • 相关阅读:
    SQL 操作结果集 -并集、差集、交集、结果集排序
    MongoDB系列四:解决secondary的读操作
    org.apache.hadoop.ipc.RemoteException: User: root is not allowed to impersonate root
    hive 中窗口函数row_number,rank,dense_ran,ntile分析函数的用法
    FormData上传文件同时附带其他参数
    Hive删除分区
    Hive日期格式转换用法
    HIVE 不支持group by 别名
    ODS与EDW的区别
    hive数据类型转换、字符串函数、条件判断
  • 原文地址:https://www.cnblogs.com/xiongtao/p/11152159.html
Copyright © 2020-2023  润新知