zoukankan      html  css  js  c++  java
  • poj 3522【Slim Span】

    题意:给你一个无向图,没有重边,没有自环,要你求该图中一颗生成树,但是这个生成树的最大边与最小边的差值要最小。

    如果固定一个最小边,求得最小生成树后,最大边也就知道了,其实这个也意味着在固定最小边的情况下最小生成树的最大边是固定的,可是为什么我们一定要求最小生成树呢,因为其他的生成树的最大边与最小边的差值要大于等于最小生成树的大小边之差,这个的原因大家可以自己仔细想想最小生成树的性质和次小生成树的求法(枚举每条最小生成树上的边,不要此条边求得的生成树,选最小一个就是了,这个就意味着次小生成树里面肯定有一条边要比最小生成树的大,其它的相同)。这样说来的话,我们只需将边排好序后,枚举每条边,并用Krustral求得最小生成树就可以了……(参考:http://blog.csdn.net/sdj222555/article/details/7698978

    View Code
     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 struct node
     8 {
     9     int x,y;
    10     int w;
    11 }edge[10000];
    12 int father[110];
    13 int n,m;
    14 
    15 bool cmp(const node& a,const node& b)
    16 {
    17     return a.w < b.w;
    18 }
    19 
    20 int find(int x)
    21 {
    22     return father[x] = (x == father[x]?x:(find(father[x])));
    23 }
    24 
    25 int Krustral(int x)
    26 {
    27     int num = 0;
    28     int ans = -1;
    29     for(int i = x;i < m;i ++)
    30     {
    31         int fa = find(edge[i].x);
    32         int fb = find(edge[i].y);
    33         if(fa == fb)
    34         {
    35             continue;
    36         }
    37         father[fa] = fb;
    38         num ++;
    39         if(num == n-1)
    40         {
    41             ans = edge[i].w;
    42             break;
    43         }
    44     }
    45     return ans;
    46 }
    47 
    48 int main()
    49 {
    50     //freopen("in.txt","r",stdin);
    51    // freopen("out.txt","w",stdout);
    52     while(cin >> n >> m,n||m)
    53     {
    54         for(int i = 0;i < m;i ++)
    55         {
    56             cin >> edge[i].x >> edge[i].y >> edge[i].w;
    57         }
    58         if(m < n - 1)
    59         {
    60             cout << "-1" << endl;
    61             continue;
    62         }
    63         sort(edge,edge+m,cmp);
    64         int minn = -1;
    65         for(int i = 0;i <= m - n + 1;i ++)
    66         {
    67             for(int j = 1;j <= n;j ++)
    68             {
    69                 father[j] = j;
    70             }
    71             int ans = Krustral(i);
    72             if(ans != -1)
    73             {
    74                 if(minn == -1 || minn > ans - edge[i].w)
    75                 {
    76                     minn = ans - edge[i].w;
    77                 }
    78             }
    79         }
    80         cout << minn << endl;
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    九度OJ 1131:合唱队形 (DP、最长上升下降序列)
    九度OJ 1130:日志排序 (排序)
    九度OJ 1129:Skew数 (大数运算)
    九度OJ 1128:求平均年龄 (基础题)
    九度OJ 1127:简单密码 (翻译)
    九度OJ 1126:打印极值点下标 (基础题)
    九度OJ 1125:大整数的因子 (大数运算)
    九度OJ 1124:Digital Roots(数根) (递归)
    存储过程
    Cookie 和 Session
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2667448.html
Copyright © 2011-2022 走看看