• 次小生成树 克鲁斯卡尔修改


        http://bailian.openjudge.cn/practice/1679?lang=en_US

    题意 判断最小生成树是否唯一 如果唯一输出大小 不唯一输出Not Unique!
    O(n*n+mlogm)
    AC代码
     1 #include <bits/stdc++.h>
     2 #define pb push_back
     3 #define mp make_pair
     4 #define fi first
     5 #define se second
     6 #define all(a) (a).begin(), (a).end()
     7 #define fillchar(a, x) memset(a, x, sizeof(a))
     8 #define huan printf("
    ");
     9 #define debug(a,b) cout<<a<<" "<<b<<" "<<endl;
    10 using namespace std;
    11 const int maxn=1e3+10,inf=0x3f3f3f3f;
    12 typedef long long ll;
    13 int n,m;
    14 struct edge
    15 {
    16     int u,v,w;
    17     bool vis;
    18 }e[maxn*10];
    19 vector<int>G[maxn];
    20 int per[maxn],maxdis[maxn][maxn];
    21 bool cmp(edge a,edge b)
    22 {
    23     return a.w < b.w;
    24 }
    25 int _find(int x)
    26 {
    27     return x == per[x] ? x: per[x] = _find(per[x]);
    28 }
    29 void kruskal()
    30 {
    31     sort(e,e+m,cmp);
    32     for(int i=0; i<=n; i++)//初始化
    33     {
    34         G[i].clear();
    35         G[i].push_back(i);
    36         per[i]=i;
    37     }
    38     int MST=0,jishu=0;//MST是最小生成树的值
    39     for(int i=0; i<m; i++)
    40     {
    41         if(jishu==n-1)  break;//小优化
    42         int x1=_find(e[i].u),x2=_find(e[i].v);
    43         if(x1!=x2)
    44         {
    45             jishu++;
    46             e[i].vis=true;//这条边已经用过了
    47             MST+=e[i].w;
    48             per[x1]=x2;
    49             for(int j=0; j<G[x1].size(); j++)//更新两点之间距离的最大值,每次合并两个等价类时分别属于两个等价类的两个点之间的最长边一定是当前加入的边
    50                 for(int k=0; k<G[x2].size(); k++)
    51                     maxdis[G[x1][j]][G[x2][k]]=maxdis[G[x2][k]][G[x1][j]]=e[i].w;//因为后面的边会越来越大,所以这里可以直接等于当前边的长度
    52             vector<int> temp=G[x2];        //现在已经属于一棵树了,那么我们就将点添加到相应的集合中
    53             for(int j=0; j<G[x1].size(); j++)
    54                 G[x2].push_back(G[x1][j]);
    55             for(int j=0; j<temp.size(); j++)
    56                 G[x1].push_back(temp[j]);
    57         }
    58     }
    59     int SecondST=inf;//次小生成树的权值
    60     for(int i=0; i<m; i++)
    61         if(!e[i].vis)
    62             SecondST=min(SecondST,MST+e[i].w-maxdis[e[i].u][e[i].v]);
    63     if(SecondST>MST)
    64         printf("%d
    ",MST);
    65     else
    66         printf("Not Unique!
    ");
    67 }
    68 int main()
    69 {
    70     int T;
    71     scanf("%d
    ",&T);
    72     while(T--)
    73     {
    74         scanf("%d%d",&n,&m);
    75         for(int i=0; i<m; i++)
    76         {
    77             scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    78             e[i].vis = false;
    79         }
    80         kruskal();
    81     }
    82     return 0;
    83 }
     
  • 相关阅读:
    pip遇见的format问题
    opencv配置
    WPF学习笔记2
    WPF笔记1 用VS2015创建WPF程序
    C#基础知识
    电脑中毒了。
    感觉又学到了不少,在这里写下来,但也有一个问题,不知道是为甚吗?
    通过对HTML有一定的了解后,现在我开始学HTML DOM了。
    此情可待成追忆,只是当时已惘然。
    常用PS快捷键
  • 原文地址:https://www.cnblogs.com/stranger-/p/9683709.html
Copyright © 2020-2023  润新知