1. 程式人生 > >判斷最小生成樹是否為一(krustra)

判斷最小生成樹是否為一(krustra)

具體思路:

首先跑一遍最短路演算法,然後將使用到的邊標記一下,同時使用一個數組記錄每一個權值出現的次數,如果出現過的權值超過一次,那麼每一次標記一條標記過的邊,再去跑最短路演算法,如果去除這條邊之後的權值和未未去除的時候的權值相同,那麼這個最短生成樹就不是唯一的,否則就是唯一的。

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!\n");
        else printf("%d\n",ans);
    }
    return 0;
}