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 }
  • 相关阅读:
    Oracle创建序列,删除序列
    java base58
    百度地图 显示,定位,轮廓图
    百度地图 圈出省份轮廓图并高亮
    基于双向链表的增删改查和排序(C++实现)
    统计字母出现次数
    线程安全
    C++面试秘笈笔记
    牛客选择题刷题
    new delete 浅析
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2667448.html
Copyright © 2011-2022 走看看