dreamxr
精诚所至,金石为开!

导航

 

题目描述

  判定最小生成树是否唯一...

分析

 根据Kruskal算法构造最小生成树的思路,我们可知出现不唯一生成树的条件即为有权值相同的边,所以在求出最小生成树后,我们可以删除其中一条有相同权值的边,再次构造生成树,如果此时生成树的权值和原来的相同,那么生成树就不唯一.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 10010
using namespace std;
struct Edge{
    int u,v,len;
    bool same,del,used;//是否有相同权值的边,是否被删除,此边是否被使用
}edge[N];
bool f;
bool cmp(Edge a ,Edge b){
    return a.len<b.len;
}
int root[N],rank[N],n,m,t;
int find(int x){
    return x==root[x]?root[x]:root[x]=find(root[x]);
}
int Union(int x,int y){
    int xx=find(x),yy=find(y);
    if(xx!=yy){
        if(rank[xx]>rank[yy]){
            root[yy]=xx;
            rank[xx]+=rank[yy];
        }
        else{
            root[xx]=yy;
            rank[yy]+=rank[xx];
        }
        return 1;
    }
    return 0;
}
int Kruskal(int n,int m){
    int ans=0;
    for(int i=1;i<=n;i++){
        root[i]=i;
        rank[i]=0;
    }
    for(int i=0;i<m;i++){
        if(edge[i].del)continue;
        int rootu=find(edge[i].u);
        int rootv=find(edge[i].v);
        if(Union(rootu,rootv)){
            ans+=edge[i].len;
            if(f) edge[i].used=1;
        }
    }
    return ans;
}
int main(){
    cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i=0;i<m;i++){
            cin>>edge[i].u>>edge[i].v>>edge[i].len;
            edge[i].same=edge[i].used=edge[i].del=0;
        }
        for(int i=0;i<m-1;i++)
            for(int j=i+1;j<m;j++)
                if(edge[i].len==edge[j].len){
                    edge[i].same=edge[j].same=1;
                }
        sort(edge,edge+m,cmp);
         f=1;
        int ans=Kruskal(n,m);
        f=0;
        int i;
        for(i=0;i<m;i++){
            if(edge[i].used&&edge[i].same){
                edge[i].del=1;
                int ans2=Kruskal(n,m);
                if(ans==ans2){
                    cout<<"Not Unique!"<<endl;
                    break;
                }
                edge[i].del=0;
            }
        }
        if(i>=m)
            cout<<ans<<endl;
    }
    return 0;
}
posted on 2012-09-03 07:31  dreamxr  阅读(85)  评论(0编辑  收藏  举报