Uva 1395

来源:互联网 发布:java截最后一次出现 编辑:程序博客网 时间:2024/06/05 03:24

题目链接:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105277#problem/B

题意:

给出一个n节点的图,边最多为n*(n-1)/2条边,求苗条度(最大边权值减最小边权值)尽量小的生成树。

分析:

按权值从小到大排序,从小到大枚举L,然后直到连通边数有n-1时,就枚举另一个L,保存最优值就可以了。

#include <stdio.h>#include <algorithm>#define INF 0x7fffffffconst int maxn = 105;struct node{    int x, y, v;    friend bool operator < ( node n1, node n2 )    {        return n1.v < n2.v; //权值排序    }}a[maxn*maxn];int fa[maxn];void init ( int n ){    for ( int i = 1; i <= n; i ++ )        fa[i] = i;}int find ( int x ) { return fa[x] == x ? x : fa[x] = find ( fa[x] ); }inline int Min ( int a, int b ) { return a < b ? a : b; }inline int Max ( int a, int b ) { return a > b ? a : b; }int main ( ){    int n, m;    while ( ~ scanf ( "%d%d", &n, &m ) && ( n || m ) )    {        for ( int i = 0; i < m; i ++ )            scanf ( "%d%d%d", &a[i].x, &a[i].y, &a[i].v );        std :: sort ( a, a+m );        int ans = INF;        for ( int i = 0; i < m; i ++ )        {            init ( n );            int cnt = 0, mn, mx, j;            mn = INF, mx = 0;            for ( j = i; j < m; j ++ )            {                int fx = find ( a[j].x ), fy = find ( a[j].y );                if ( fx != fy )                {                    fa[fx] = fy;                    cnt ++; //统计连通的边数                    mn = Min ( mn, a[j].v );                    mx = Max ( mx, a[j].v );                }                if ( cnt >= n-1 )   //n-1条证明生成树已完成                    break ;            }            if ( j < m )                ans = Min ( ans, mx-mn );   //找最小值        }        printf ( "%d\n", ans == INF ? -1 : ans );    }    return 0;}


0 0
原创粉丝点击