POJ 1679 The Unique MST

它的结论是最小生成树是独一无二的。


先扫在边缘。确定双方平等和标记 vis;


然后生成最小生成树,总重量值至 ans。并且这是在第一代侧使用的记录。use。


最后扫描全部边,有相等的。而且使用的边。

把它标记为删除 del。然后生成最小生成树。

假设跟第一颗树权值一样。表明生成树不是唯一的。


#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<iostream>
#include<list>
#include<set>
#include<cmath>
#define INF 0x7fffffff
#define eps 1e-6
using namespace std;
int n,m;
int fa[101];
struct lx
{
    int u,v,len;
} l[101*50];
int father(int x)
{
    if(x!=fa[x])
        return fa[x]=father(fa[x]);
}
bool cmp(lx a,lx b)
{
    return a.len<b.len;
}
bool vis[101*50];
bool use[101*50];
bool del[101*50];
int Kruskal(bool flag)
{
    for(int i=0; i<=n; i++)
        fa[i]=i;
    int point=1,ans=0;
    for(int i=0; i<m; i++)
    {
        if(del[i])continue;
        int u=father(l[i].u);
        int v=father(l[i].v);
        if(u==v)continue;
        fa[u]=v;
        point++;
        if(flag)use[i]=1;
        ans+=l[i].len;
        if(point>=n)break;
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<m; i++)
            scanf("%d%d%d",&l[i].u,&l[i].v,&l[i].len);
        sort(l,l+m,cmp);
        memset(vis,0,sizeof(vis));
        memset(use,0,sizeof(use));
        memset(del,0,sizeof(del));
        for(int i=0; i<m-1; i++)
            if(l[i].len==l[i+1].len)vis[i]=vis[i+1]=1;

        int bt1=Kruskal(1);
        bool flag=1;

        for(int i=0; i<m; i++)
        {
            if(vis[i]&&use[i])
            {
                del[i]=1;
                int bt2=Kruskal(0);
                if(bt1==bt2)
                {
                    flag=0;
                    break;
                }
                del[i]=0;
            }
        }
        if(flag)printf("%d
",bt1);
        else printf("Not Unique!
");
    }
}


版权声明:本文博客原创文章。博客,未经同意,不得转载。

原文地址:https://www.cnblogs.com/blfshiye/p/4687191.html