题解 | 还是畅通工程

还是畅通工程

https://www.nowcoder.com/practice/d6bd75dbb36e410995f8673a6a2e2229

#include <iostream>
#include <map>
#include <algorithm>

using namespace std;

struct Road{
    int _from;
    int _to;
    int _distance;
    bool operator<(const Road& rhs)const{
        return this->_distance < rhs._distance;
    }
};

#define N 5000
Road roads[N] = {0};
map<int,int> father;
map<int,int> height;

int FindRoot(int n){
    if(father[n] != n){
        father[n] = FindRoot(father[n]);
    }
    return father[n];
}

void Union(int n1, int n2){
    int root1 = FindRoot(n1);
    int root2 = FindRoot(n2);
    if(root1 == root2)  // 其实这一句永远执行不到,因为我们是判断之后才合并的
        return ;    // 这两行可以省略   
    // 矮树合并到高树中
    if(height[root1] > height[root2]){
        father[root2] = root1;
    }else if(height[root1] < height[root2]){
        father[root1] = root2;
    }else { // 两棵树一样高
        father[root2] = root1;  // 让2树合并到1树中
        height[root1]++;    // 1树的高度+1
    }
}

int main()
{
    int n;  // 村庄总数
    while(cin >> n &&  n != 0){
        int totalRoad = n*(n-1)/2;
        // 先录入所有路径信息
        for(int i = 0; i < totalRoad; ++i){
            scanf("%d%d%d", &roads[i]._from, &roads[i]._to, &roads[i]._distance);
        }
        // 根据路径信息生成最小生成树
        // 先对路径信息按照distance进行升序排序
        sort(&roads[0],&roads[totalRoad]);
        // 排完序之后按照克鲁斯卡尔算法生成最小生成树
        int sum = 0;
        for(int i = 0; i < totalRoad; ++i){
            int start = roads[i]._from; // 只是因为名字太长,换一个短一点的
            int end = roads[i]._to;
            int dist = roads[i]._distance;
            // 如果该节点为新节点
            if(father.count(start) == 0){
                father[start] = start;  // 以该节点为根节点建树
                height[start] = 1;  // 树高为1
            }
            if(father.count(end) == 0){ // 同上
                father[end] = end;
                height[end] = 1;
            }
            // 到此,两个节点一定都在集合中
            if(FindRoot(start) == FindRoot(end)){   // 两节点已经连通
                continue;   // 直接下一条边
            }else { // 两节点在不同的集合中
                Union(start, end);
                sum += dist;
            }
        }
        cout << sum << endl;
    }

    return 0;
}

全部评论
自测输入跑出来的结果是错的,但是提交是AC的,大佬们开出来哪里错了的话麻烦告诉我一下,球球
点赞 回复 分享
发布于 02-11 21:06 江苏

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务