zoukankan      html  css  js  c++  java
  • UVa 1395 苗条的生成树(Kruskal+并查集)

    https://vjudge.net/problem/UVA-1395

    题意:

    给出一个n结点的图,求苗条度(最大边减最小边的值)尽量小的生成树。

    思路:

    主要还是克鲁斯卡尔算法,先仍是按权值排序,对于一个连续的边集区间[L,R],如果这些边使得n个点全部连通,则一定存在一个苗条度不超过W[R]-W[L]的生成树。从小到大枚举L,对于每个L,从小到大枚举R。

    这道题目我一直超时,最后发现数组开小了,我一直以为数组开小了肯定会出来Runtime error的...

     1 #include<iostream> 
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 100 + 5;
     7 
     8 int n, m, ans;
     9 int p[maxn];
    10 
    11 struct node
    12 {
    13     int u;
    14     int v;
    15     int w;
    16 }edge[maxn*maxn];
    17 
    18 int find(int x)
    19 {
    20     return p[x] == x ? x : find(p[x]);
    21 }
    22 
    23 bool cmp(node a, node b)
    24 {
    25     return a.w < b.w;
    26 }
    27 
    28 
    29 void init()
    30 {
    31     for (int k = 1; k <= n; k++)   p[k] = k;
    32 }
    33 
    34 void Kruskal()
    35 {
    36     int ok = 0;
    37     sort(edge, edge + m, cmp);
    38     for (int i = 0; i <= m - n + 1; i++)
    39     {
    40         int num = 0;
    41         init();
    42         for (int j = i ; j < m; j++)
    43         {
    44             int x = find(edge[j].u);
    45             int y = find(edge[j].v);
    46             if (x != y)
    47             {
    48                 p[x] = y;
    49                 num++;
    50             }
    51             if (num == n - 1)
    52             {
    53                 ans = min(ans, edge[j].w - edge[i].w);
    54                 ok = 1;
    55                 break;
    56             }
    57         }
    58         while (edge[i].w == edge[i + 1].w)   i++;
    59     }
    60     if (!ok)    printf("-1
    ");
    61     else         printf("%d
    ", ans);
    62 }
    63 
    64 int main()
    65 {
    66     //freopen("D:\txt.txt", "r", stdin);
    67     while (scanf("%d%d",&n,&m))
    68     {
    69         if (n == 0 && m == 0)    break;
    70         for (int i = 0; i<m ; i++)
    71         {
    72             scanf("%d%d%d", &edge[i].u, &edge[i].v , &edge[i].w);
    73         }
    74         ans = 1000000000;
    75         Kruskal();
    76     }
    77     return 0;
    78 }
    79     
  • 相关阅读:
    第三次作业
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    随笔
    第五次作业
    第四次作业
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6387800.html
Copyright © 2011-2022 走看看