zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SGU 271 Book Pile (双端队列)
    POJ 3110 Jenny's First Exam (贪心)
    HDU 4310 Hero (贪心)
    ZOJ 2132 The Most Frequent Number (贪心)
    POJ 3388 Japanese Puzzle (二分)
    UVaLive 4628 Jack's socks (贪心)
    POJ 2433 Landscaping (贪心)
    CodeForces 946D Timetable (DP)
    Android Studio教程从入门到精通
    Android Tips – 填坑手册
  • 原文地址:https://www.cnblogs.com/xiongtao/p/11152159.html
Copyright © 2011-2022 走看看