poj 1679 The Unique MST ([kuangbin带你飞]专题八 生成树 )

来源:互联网 发布:mac os 修复磁盘权限 编辑:程序博客网 时间:2024/06/07 20:01

题目大意:给你一个无向图,问如果这个无向图的最小生成树是唯一的就输出最小生成树的权值,否则输出Not Unique!

解题思路,求次小生成树,如果次小生成树中有何最小的权值一样的,则生成树不唯一,否则唯一用Kruskal,求最小生成树,然后枚举其中一个边去掉以后(n-1条),再求最小生成树,然后和原来的权值比较,


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100+10;int n,m;struct Node{    int u,v;    int cost;}node[maxn*maxn];bool cmd(Node a,Node b){    return a.cost<b.cost;}int s_tree[maxn];int pa[maxn];int find(int x){    if(pa[x]==x) return x;    else return pa[x]=find(pa[x]);}void join(int x,int y){    int root1=find(x);    int root2=find(y);    if(root1!=root2){        pa[root2]=root1;    }}bool same(int x,int y){    return find(x)==find(y);}void Kruskal(){    for(int i=0;i<=n;i++){        pa[i]=i;    }    memset(s_tree,0,sizeof(s_tree));    int k=0;    int ans=0,ans1=0;    for(int i=0;i<m &&k<n-1; i++){        int u,v;        u=node[i].u;        v=node[i].v;        if(!same(u,v)){            ans+=node[i].cost;            join(u,v);            s_tree[k++]=i;        }    }    int k1=0;    for(int i=0;i<n-1;i++){        ans1=0;        k1=0;        for(int j=0;j<=n;j++) pa[j]=j;        for(int j=0;j<m;j++){            if(s_tree[i]==j) continue;            int u=node[j].u;            int v=node[j].v;            if(!same(u,v)){                k1++;                ans1+=node[j].cost;                join(u,v);            }        }        if(k1!=n-1) continue;        if(ans==ans1){            printf("Not Unique!\n");            return ;        }    }    printf("%d\n",ans);}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        for(int i=0;i<m;i++){            int u,v,cost;            scanf("%d%d%d",&u,&v,&cost);            node[i].u=u;            node[i].v=v;            node[i].cost=cost;        }        sort(node,node+m,cmd);        Kruskal();    }    return 0;}



0 0