首页 > 代码库 > poj 1679 The Unique MST (判断最小生成树是否唯一)

poj 1679 The Unique MST (判断最小生成树是否唯一)

链接:poj 1679

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

若唯一,输出最小权值和,否则,输出  Not Unique!


判断最小生成树是否唯一的思路:

1、对图中的每一条边,扫描其他边,如果存在相同权值的边,则对该边做标记

2、然后用Kruskal算法或Prim算法求MST

3、求得MST后,如果该MST中未包含做了标记的边,即可判断MST唯一

如果包含做了标记的边,则依次去掉这些边的一条边,再求MST,

如果求得的MST权值和原来的MST的权值一样,即可判断MST不唯一。


个人思路是先求最小生成树,并标记最小生成树包含的边,

再依次判断是否有相同权值的边,若存在,将最小生成树的该条边去掉,

重新求最小生成树,若得到的权值与原来的最小权值和相等,则不唯一


#include<stdio.h>
#include<algorithm>
#include<string.h>
#define INF 999999
using namespace std;
int n,m,k,f[105],path[105];
struct stu
{
    int u,v,w;
}edge[10010];
int cmp(stu a,stu b)
{
    return a.w<b.w;
}
int find(int x)
{
    if(x!=f[x])
        f[x]=find(f[x]);
    return f[x];
}
int kruskal(int flag)
{
    int i,x,y,sum=0;
    for(i=1;i<=n;i++)
        f[i]=i;
    k=0;
    for(i=1;i<=m;i++){
        if(edge[i].w==INF)
            continue;
        x=find(edge[i].u);
        y=find(edge[i].v);
        if(x!=y){
            sum+=edge[i].w;
            if(flag)
                path[k]=i;  //第一次求最小生成树时记录路径
            k++;
            if(k==n-1)
                break;
            f[x]=y;
        }
    }
    if(k!=n-1)
        sum=-1;
    return sum;
}
int main()
{
    int T,i,j,ans,s,t,flag,num;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        memset(edge,0,sizeof(edge));
        for(i=1;i<=m;i++)
            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
        sort(edge+1,edge+m+1,cmp);
        ans=kruskal(1);
        flag=1;
        num=k;
        for(i=0;i<num&&flag;i++){
            j=path[i];             //依次判断是否存在与路径相同权值的边
            if(edge[j-1].w==edge[j].w||edge[j+1].w==edge[j].w){  
                t=edge[j].w;
                edge[j].w=INF;       //若存在,将其标记为极大值,表示去掉此边,再求最小生成树
                s=kruskal(0);
                if(s==ans)
                    flag=0;
                edge[j].w=t;        //将该边还原为原值
            }
        }
        if(!flag)
            printf("Not Unique!\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}


poj 1679 The Unique MST (判断最小生成树是否唯一)