判断最小生成树是否为一(krustra)

题目链接:https://vjudge.net/contest/66965#problem/K

具体思路:

首先跑一遍最短路算法,然后将使用到的边标记一下,同时使用一个数组记录每一个权值出现的次数,如果出现过的权值超过一次,那么每一次标记一条标记过的边,再去跑最短路算法,如果去除这条边之后的权值和未未去除的时候的权值相同,那么这个最短生成树就不是唯一的,否则就是唯一的。

AC代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stdio.h>
using namespace std;
# define maxn 100000+10
# define inf 0x3f3f3f3f
# define ll long long
int n,m,tt;
int vis[maxn];
int father[maxn];
int first;
struct node
{
    int num;
    int fr;
    int to;
    int cost;
    int chu;
} q[maxn];
bool cmp(node t1,node t2)
{
    return t1.cost<t2.cost;
}
int Find(int t)
{
    return t==father[t]? t: father[t]=Find(father[t]);
}
int krustra(int w)
{
    for(int i=1; i<=n; i++)
    {
        father[i]=i;
    }
    int sum=0;
    for(int i=1; i<=tt; i++)
    {
        if(q[i].num==w)continue;
        int s1=Find(q[i].fr);
        int s2=Find(q[i].to);
        if(s1!=s2)
        {
            sum+=q[i].cost;
            father[s1]=s2;
            if(first==1){//第一次记录未去掉边的时候的所选的边。
            q[i].chu=1;
            }
        }
    }
    return sum;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&m);
        tt=0;
        int t1,t2,t3;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&t1,&t2,&t3);
            q[++tt].fr=t1;
            q[tt].to=t2;
            q[tt].cost=t3;
            q[tt].num=i;
            q[tt].chu=0;
            q[++tt].fr=t2;
            q[tt].to=t1;
            q[tt].cost=t3;
            q[tt].num=i;
            vis[t3]++;
            q[tt].chu=0;//
        }
        sort(q+1,q+tt+1,cmp);
        first=1;
        int ans=krustra(0);
        first=0;
        int flag=0;
        for(int i=1; i<=tt; i++)
        {
            if(vis[q[i].cost]>=2&&q[i].chu==1)//如果这条边的权值出现过不止一次并且在最短路中出现过,那么这条边就成为了实验对象。
            {
                int temp=krustra(q[i].num);
                if(temp==ans)
                {
                    flag=1;
                    break;
                }
            }
        }
        if(flag==1)printf("Not Unique!
");
        else printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/letlifestop/p/10262865.html