poj-1679-The Unique MST-最小生成树是否唯一

判断MST(最小生成树)是否唯一的算法:

下面给大家介绍用Kruscal的简单变形就可以解决本题,时间复杂度为O(M+MlogM),包括了快排的时间复杂度,0MS。

注意到Kruscal贪心每次找出边权最小的边判断能否合并,假设找到了一条边权最小的边,其两个顶点所在集合的根节点分别为x和y,

向后搜寻边权与当前边相同的边(即当前边权最小的边不唯一),若搜寻到的边两个顶点的根节点同样是x和y,则这两个集合合并就有了两种方法,

此时就可以直接输出NotUnique!并退出。这样除了qsort以外的时间复杂度就被控制在O(m)以内。

#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
using namespace std;
#define maxm 20000
#define maxn 150
struct list
{
    int u,v,w;
    friend bool operator < (const list &a,const list &b)
    {
        return a.w<b.w;
    }
} edge[maxm],p,q;
int vis[maxm];
int f[maxn];
int find(int x)
{
    while(x!=f[x])x=f[x];
    return x;
}
int vp[maxm];
int maps[maxn][maxn];
int pan(int a,int b,int c,int d)
{
    if(a==c&&b==d)return 1;
    if(a==d&&b==c)return 1;
    return 0;
}
int main()
{
    int T,n,m,i;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(maps,0,sizeof(maps));
        for(i=1; i<=n; i++)f[i]=i;
        for(i=1; i<=m; i++)scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
        sort(edge+1,edge+m+1);
        memset(vis,0,sizeof(vis));
        for(i=2; i<=m; i++)
        {
            if(edge[i].w==edge[i-1].w)vis[i]=vis[i-1]=1;
        }
        int ans=0;
        int leap=0;
        int j;
        queue<list>que;
        while(!que.empty())que.pop();
        for(i=1; i<=m; i++)
        {
            int a=find(edge[i].u);
            int b=find(edge[i].v);
            if(a==b)continue;
            p.u=a;
            p.v=b;
            que.push(p);
            for(j=i+1;j<=m;j++)
            {
                if(edge[j].w==edge[i].w)
                {
                    int aa=find(edge[j].u);
                    int bb=find(edge[j].v);
                    if(aa==bb)continue;
                    p.u=a;
                    p.v=b;
                    que.push(p);
                }
                else break;
            }
            i=j-1;
            while(!que.empty())
            {
                p=que.front();
                que.pop();
                a=p.u;
                b=p.v;
                if(f[a]==b||f[b]==a)
                {
                    leap=1;
                    break;
                }
                f[a]=b;
            }
            if(leap==1)break;
            ans+=edge[i].w;
            f[a]=b;
        }
        if(leap)cout<<"Not Unique!"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(poj-1679-The Unique MST-最小生成树是否唯一)