• UVA-10462.Is There A Second Way Left(Kruskal+次小生成树)


    题目链接

    本题大意:这道题用Kruskal较为容易

    参考代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 100 + 5, maxe = 200 + 5, INF = 0x3f3f3f3f;
     8 int n, m, pir[maxn], Max[maxn][maxn];
     9 vector <int> G[maxn];
    10 struct Edge {
    11     int u, v, w;
    12     bool vis;
    13 }edge[maxe];
    14 
    15 int Find(int x) {
    16     if(x == pir[x]) return x;
    17     return pir[x] = Find(pir[x]);
    18 }
    19 
    20 bool cmp(const Edge &a, const Edge &b) {
    21     return a.w < b.w;
    22 }
    23 
    24 int Kruskal() {
    25     sort(edge + 1, edge + m + 1, cmp);
    26     int ans = 0, cnt = 0;
    27     for(int i = 1; i <= n; i ++) {
    28         G[i].clear();
    29         G[i].push_back(i);
    30         pir[i] = i;
    31     }
    32     for(int i = 1; i <= m; i ++) {
    33         int fx = Find(edge[i].u), fy = Find(edge[i].v);
    34         if(cnt == n - 1) break;
    35         if(fx != fy) {
    36             cnt ++;
    37             edge[i].vis = true;
    38             ans += edge[i].w;
    39             int len_fx = G[fx].size(), len_fy = G[fy].size();
    40             for(int j = 0; j < len_fx; j ++) {
    41                 for(int k = 0; k < len_fy; k ++) {
    42                     Max[G[fx][j]][G[fy][k]] = Max[G[fy][k]][G[fx][j]] = edge[i].w;
    43                 }
    44             }
    45             pir[fx] = fy;
    46             for(int j = 0; j < len_fx; j ++)
    47                 G[fy].push_back(G[fx][j]);
    48         }
    49     }
    50     if(cnt < n - 1) return INF;
    51     return ans;
    52 }
    53 
    54 int Second_Kruskal(int MST) {
    55     int ans = INF;
    56     for(int i = 1; i <= m; i ++) {
    57         if(!edge[i].vis)
    58             ans = min(ans, MST + edge[i].w - Max[edge[i].u][edge[i].v]);
    59     }
    60     return ans;
    61 }
    62 
    63 int main () {
    64     int t, Case = 0;
    65     scanf("%d", &t);
    66     while(t --) {
    67         scanf("%d %d", &n, &m);
    68         for(int i = 1; i <= m; i ++) {
    69             scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w);
    70             edge[i].vis = false;
    71         }
    72         printf("Case #%d : ", ++Case);
    73         int MST = Kruskal();
    74         if(MST == INF) {
    75             printf("No way
    ");
    76             continue;
    77         }
    78         int Second_MST = Second_Kruskal(MST);
    79         if(Second_MST == INF) printf("No second way
    ");
    80         else printf("%d
    ", Second_MST);
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    输入/输出的格式和方法
    程序编译运行和exe运行之文件位置的区别
    ZOJ_3950_How Many Nines 解题报告及如何对程序进行测试修改
    [Offer收割]编程练习赛13 解题报告
    查找语言自带函数
    codeblocks下的汇编语言
    hiho一下 第144周(机会渺茫)解题报告及拓展
    关闭调试窗口快捷方式
    编写程序一个位置的快速到达和修改
    poj3660(Cow Contest)解题报告
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10837395.html
Copyright © 2020-2023  润新知