• UVA 10600 ACM Contest and Blackout (次小生成树)


    题目大意:

      给n个节点,m条边,问最小生成树,次小生成树?

      ps:以前做次小生成树的时候估计没有掌握牢固,这次wa的好辛苦哟。

     1 #include <cmath>
     2 #include <queue>
     3 #include <string>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <iostream>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 const int maxn = 100;
    11 const int INF = 0x3f3f3f3f;
    12 const double Exp = 1e-10;
    13 
    14 int cost[maxn+10][maxn+10], lowc[maxn+10], vis[maxn+10];
    15 int Max[maxn+10][maxn+10], used[maxn+10][maxn+10], pre[maxn+10];
    16 int n;
    17 void init ()
    18 {
    19     for (int i=1; i<=n; i++)
    20         for (int j=1; j<=n; j++)
    21             if (i == j)
    22                 cost[i][j] = 0;
    23             else
    24                 cost[i][j] = INF;
    25 }
    26 int prim ()
    27 {
    28     int i, j, sum = 0;
    29     memset (Max, 0, sizeof(Max));
    30     memset (used, 0, sizeof(used));
    31     memset (vis, 0, sizeof(vis));
    32     vis[1] = 1;
    33     for (i=1; i<=n; i++)
    34     {
    35         lowc[i] = cost[1][i];
    36         pre[i] = 1;
    37     }
    38     for (i=1; i<n; i++)
    39     {
    40         int p, mini = INF;
    41         for (j=1; j<=n; j++)
    42             if (!vis[j] && mini > lowc[j])
    43             {
    44                 p = j;
    45                 mini = lowc[j];
    46             }
    47         vis[p] = 1;
    48         sum += mini;
    49         used[pre[p]][p] = used[p][pre[p]] = 1;
    50         for (j=1; j<=n; j++)
    51         {//这一点的错误wa的好苦
    52             if (vis[j] && j != p)//p!=j一定要有,否则Max[i][i]的距离就可能会不等于零,影响后面的计算过程
    53                 Max[j][p] = Max[p][j] = max(Max[j][pre[p]], lowc[p]);
    54             if (!vis[j] && lowc[j] > cost[p][j])
    55             {
    56                 lowc[j] = cost[p][j];
    57                 pre[j] = p;
    58             }
    59         }
    60     }
    61     return sum;
    62 }
    63 int smst (int sum)
    64 {
    65     int i, j, mini = INF;
    66     for (i=1; i<=n; i++)
    67         for (j=i+1; j<=n; j++)
    68             if (cost[i][j] != INF && !used[i][j])
    69                 mini = min (mini, sum + cost[i][j] - Max[i][j]);
    70     return mini;
    71 }
    72 int main ()
    73 {
    74     int t, m;
    75     scanf ("%d", &t);
    76     while (t --)
    77     {
    78         scanf ("%d %d", &n, &m);
    79         init ();
    80         while (m --)
    81         {
    82             int a, b, c;
    83             scanf ("%d %d %d", &a, &b, &c);
    84             cost[a][b] = cost[b][a] = c;
    85         }
    86         int num1, num2;
    87         num1 = prim ();
    88         num2 = smst (num1);
    89         printf ("%d %d
    ", num1, num2);
    90     }
    91     return 0;
    92 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    李洪强IOS经典面试题 33-计算有多少个岛屿
    李洪强iOS经典面试题32-简单介绍 ARC 以及 ARC 实现的原理
    李洪强iOS经典面试题31-解释垃圾回收的原理
    iOS音频合并
    Macbook小问题
    weex-iOS集成
    WEEX快速入门
    Mac上Nginx-增加对HLS的支持
    iOS直播-基于RTMP的视频推送
    iOS直播-播放基于RTMP协议的视频
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4549538.html
Copyright © 2020-2023  润新知