Bzoj 1083: [SCOI2005]繁忙的都市 (最小生成树)

Bzoj 1083: [SCOI2005]繁忙的都市

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1083
此题是最小瓶颈生成树的裸题.
最小瓶颈生成树:由最小的边权的\(n-1\)条边连接起\(n\)个点.
显然这就是\(Kruskal\)算法.继而得知其实就是求最小生成树,用\(prim\)也可以求.
然后这道题就成了最小生成树入门题??

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define max(a,b) a > b ? a : b
const int maxN = 300 + 7;
const int maxM = 5e4 + 7;
using namespace std;
 
struct Node {
    int u,v,w;
}Map[maxM];
int num ;
int f[maxN];
 
bool cmp(Node a,Node b) {
    return a.w < b.w;
}
 
void add_Node(int u,int v,int w) {
    Map[++ num].u = u;
    Map[num].v = v;
    Map[num].w = w;
    return;
}
 
int find(int x) {
    return f[x] == x ? x : f[x] = find(f[x]);
}
 
void unit(int u,int v) {
    int fx = find(u),fy = find(v);
    if(rand() % 2) f[fx] = fy;
    else f[fy] = fx;
    return;
}
 
inline int read() {
    int x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
    return x * f;
}
 
int main() {
    int n,m;
    n = read();m = read(); 
    for(int i = 1;i <=  n;++ i) 
        f[i] = i;
    for(int i = 1,u,v,w;i <= m;++ i) {
        u = read();v = read();w = read();
        add_Node(u,v,w);
    }
    sort(Map + 1,Map + m + 1,cmp);
    int sum = 0,k = 0;
    for(int i = 1;i <= m;++ i) {
        if(k == n - 1) break;
        int fx = find(Map[i].u),fy = find(Map[i].v);
        if(fx != fy) {
            k ++;
            sum = max(Map[i].w,sum);
            unit(Map[i].u,Map[i].v);
        }
    }
    printf("%d %d",n - 1,sum);
    return 0;
}

posted @ 2018-09-29 20:21  Rlif  阅读(90)  评论(0编辑  收藏