POJ1679 The Unique MST【次小生成树】

题意:

判断最小生成树是否唯一。

思路:

首先求出最小生成树,记录现在这个最小生成树上所有的边,然后通过取消其中一条边,找到这两点上其他的边形成一棵新的生成树,求其权值,通过枚举所有可能,通过这些权值看与原最小生成树的权值比较看其是否唯一。其实也可以理解成次小生成树加上最大边权的边后是否唯一。

代码:

krusual:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std;

typedef long long ll;
const int N=11000;
const int M=15005;
int i,j,n,m,cnt,parent[N];
bool flag;

struct man
{
    int u,v,w;
    int eq,used,del;
} edg[N];

bool cmp(man g,man h)
{
return g.w<h.w;
}

void init()
{
    for(i=0; i<=10005; i++)
    {
        parent[i]=i;
    }
}

int Find(int x)
{
    if(parent[x] != x) parent[x] = Find(parent[x]);
    return parent[x];
}//查找并返回节点x所属集合的根节点

void Union(int x,int y) {
    x = Find(x);
    y = Find(y);
    if(x == y) return;
    parent[y] = x;
}//将两个不同集合的元素进行合并

int Kruskal()
{
    init();
    int sum=0;
    int num=0;
    for(i=0;i<m;i++)
    {
        if(edg[i].del==1)continue;
        int u=edg[i].u;int v=edg[i].v;int w=edg[i].w;
        if(Find(u)!=Find(v))
        {
            sum+=w;
            if(!flag)edg[i].used=1;
            num++;
            Union(u,v);
        }
        if(num>=n-1)break;
   }
   return sum;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cnt=0;
        cin>>n>>m;
        for(i=0; i<m; i++)
        {
            cin>>edg[i].u>>edg[i].v>>edg[i].w;
            edg[i].del=0;
            edg[i].used=0;
            edg[i].eq=0;//eq没有初始化
        }
        for(i=0;i<m;i++)
        {
            for(j=0;j<m;j++)
            {
                if(i==j)continue;
                if(edg[i].w==edg[j].w)edg[i].eq=1;
            }
        }
        sort(edg,edg+m,cmp);
        flag=false;
        cnt=Kruskal();
        flag=true;
        bool gg=false;
        for(i=0;i<m;i++)
        {
            if(edg[i].used==1&&edg[i].eq==1)
            {
                edg[i].del=1;
                int s=Kruskal();//printf("%d %d\n",i,s);
                if(s==cnt)
                {
                    gg=true;
                    cout<<"Not Unique!"<<endl;
                    break;
                }
                edg[i].del=0;
            }
        }
        if(!gg) cout<<cnt<<endl;
    }
    return 0;
}
View Code

 

posted @ 2017-10-08 18:44  codeg  阅读(130)  评论(0编辑  收藏  举报