The Unique MST(次小生成树)

来源:互联网 发布:淘宝怎么看自己评价的 编辑:程序博客网 时间:2024/06/06 20:33

题意:
给你n个点,m条边,问你最小生成树是不是唯一的,如果唯一输出最小生成树的总权值大小,否则就输出“Not Unique!”
思路:
求一下次小生成树看一下是不是和最小生成树总权值大小一样即可。
关于求次小生成树:
求次小生成树

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <queue>#include <stack>using namespace std;typedef long long LL;const int MAXN = 100+5;const int inf = 1e9;int n,m;struct edge{    int u,v,w;    bool operator < (const edge &a)const    {        return w < a.w;    }} edge[MAXN*MAXN];int pre[MAXN<<1];int findx(int x){    return pre[x] == x?x:pre[x] = findx(pre[x]);}bool vis[MAXN*MAXN];void kruskal(){    sort(edge,edge+m);    //首先求一次最小生成树    for(int i = 1; i <= n; ++i)pre[i] = i;    for(int i = 0; i < m; ++i)vis[i] = 0;    int min1 = 0;    int cnt = 0;    for(int i = 0; i < m; ++i)    {        int u = edge[i].u;        int v = edge[i].v;        int w = edge[i].w;        u = findx(u);        v = findx(v);        if(u != v)        {            pre[v] = u;            cnt++;            min1 += w;            vis[i] = 1;            if(cnt == n-1)break;        }    }    //寻找次小生成树    int min2 = inf;    //枚举不是在最小生成树中的边    for(int i = 0; i < m; ++i)    {        if(vis[i])continue;        //首先把当前边加入最小生成树中        int sum = 0;        for(int i = 1; i <= n; ++i)pre[i] = i;        pre[edge[i].v] = edge[i].u;        sum += edge[i].w;        //然后继续加边构成最小生成树        cnt = 1;        for(int j = 0; j < m; ++j)        {            int u = edge[j].u;            int v = edge[j].v;            int w = edge[j].w;            u = findx(u);            v = findx(v);            if(u != v)            {                pre[v] = u;                sum += w;                cnt++;                if(cnt == n-1)                {                    min2 = min(min2,sum);                    break;                }            }        }    }    if(min2 == min1)puts("Not Unique!");    else printf("%d\n",min1);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(int i = 0; i < m; ++i)        {            scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);        }        kruskal();    }    return 0;}
原创粉丝点击