POJ 1797 Heavy Transportation(Kruskal灵活使用)(瓶颈树)

题意:

求1到n路径上最大的最小值。

原因:样例输入

1

3 3

1 2 3

1 3 4

2 3 5

1-2最多可以运输3,2-3可最多以运输5,但是2的来源只有3,所以路径1-2-3上能运输的量为3

1-3可以运输4,所以结果就是4。

可以很明显的看出一条路径上能够运输的最大值与该路径上最小的边相等,所以只需求出最大的最小值即可。

最大生成树一定是一棵瓶颈树,由瓶颈树的性质可知,最小边一定最大。

按权值从大到小排序,跑一遍Kruskal求最大生成树记录最小值,当1与n联通时,即利用并查集判断find(1)==find(n)时返回此时最小值即可。

注意输出格式,每一个例子后都有一个空行(包括最后一个例子)。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 1000 + 5;
const int inf = 0x3f3f3f3f;
int n, m, t, pre[maxn];
struct edge{
    int u, v, w;
    bool operator < ( const edge &a )const{
        return w>a.w;
    }
} ed[maxn*maxn];
inline int find( int x ){
    return pre[x]==x ? x:pre[x] = find(pre[x]);
}

inline int min( int a, int b ){
    return a<b ?a:b;
}

inline int kru(){
    sort( ed, ed+m );
    int res = inf;
    for( int i=0; i<m; i++ ){
        int fx = find(ed[i].u);
        int fy = find(ed[i].v);
        if( fx!=fy ){
            pre[fx] = fy;
            res = min( res, ed[i].w );
            if( find(1)==find(n) ) break;  //此处其实不用求min 只需当find(i)==find(n)时让res = ed[i].w 然后break即可
        }
    }
    return res;
}

int main(){
    scanf("%d", &t);
    for( int k=1; k<=t; k++ ){
        scanf("%d%d", &n, &m);
        for( int i=1; i<=n; i++ ) pre[i] = i;
        for( int i=0; i<m; i++ )
            scanf("%d%d%d",&ed[i].u, &ed[i].v, &ed[i].w);
        int ans = kru();
        printf("Scenario #%d:
", k);
        printf("%d

", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/WAautomaton/p/10917586.html