poj1679(最小生成树)

 

传送门:The Unique MST

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

分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<cmath>

#include<algorithm>

#include<queue>

#include<vector>

#define LL long long

#define INF 111111111

#define N 1010

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

struct node

{

    int u,v,w;

    bool operator<(const node &a)const

    {

        return w<a.w;

    }

}s[N*N];



int fa[N],path[N],n,m,mst,flag;



void init()

{

    for(int i=1;i<=n;i++)

    fa[i]=i;

}



int find(int x)

{

    return x==fa[x]?x:fa[x]=find(fa[x]);

}



void krustal()

{

    int cnt=0;

    mst=0;init();

    for(int i=0;i<m;i++)

    {

        int a=find(s[i].u);

        int b=find(s[i].v);

        if(a==b)continue;

        fa[a]=b;

        path[cnt++]=i;

        mst+=s[i].w;

    }

    for(int i=0;i<cnt;i++)

    {

        int sum=0,num=0;

        init();

        for(int j=0;j<m;j++)

        {

            if(j==path[i])continue;

            int a=find(s[j].u);

            int b=find(s[j].v);

            if(a==b)continue;

            fa[a]=b;

            sum+=s[j].w;

            num++;

        }

        if(num==n-1&&sum==mst){flag=0;return;}

    }

}



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",&s[i].u,&s[i].v,&s[i].w);

        }

        sort(s,s+m);

        flag=1;

        krustal();

        if(flag)

            printf("%d\n",mst);

        else

            printf("Not Unique!\n");



    }

}
View Code

 

你可能感兴趣的:(最小生成树)