最小生成树 - 还是畅通工程

还是畅通工程

http://www.nowcoder.com/questionTerminal/d6bd75dbb36e410995f8673a6a2e2229

这是一道典型的最小生成树的题目, 利用Kruskal算法,先按照road的长度排序,若当前的road未在连接好的“城市组”里,则连通它。直到所有的城市全部连通,即所铺路径最短。

// runtime: 6ms
// space: 488K
#include <iostream>
#include <algorithm>
using namespace std;

struct Road {
    int from;
    int to;
    int distance;

    bool operator< (const Road& r) const {
        return distance < r.distance;
    }
};

const int MAX = 100;

Road road[MAX * MAX];
int father[MAX];
int height[MAX];
// 并查集代码
void Initial(int n) {
    for (int i = 0; i <= n; ++i) {
        father[i] = i;
        height[i] = 0;
    }
}

int Find(int x) {
    if (x != father[x]) {
        father[x] = Find(father[x]);
    }
    return father[x];
}

void Union(int x, int y) {
    x = Find(x);
    y = Find(y);
    if (x != y) {
        if (height[x] > height[y]) {
            father[y] = x;
        } else if (height[x] < height[y]) {
            father[x] = y;
        } else {
            father[x] = y;
            height[y]++;
        }
    }
}

int Kruskal(int cityNum, int roadNum) {
    Initial(cityNum);

    sort(road, road + roadNum);
    int sum = 0;
    for (int i = 0; i < roadNum; ++i) {
        Road current = road[i];
        if (Find(current.from) != Find(current.to)) { // 核心代码
            Union(current.from, current.to);
            sum += current.distance;
        }
    }
    return sum;
}

int main() {
    int cityNum;
    while (cin >> cityNum) {
        if (cityNum == 0)
            break;

        int roadNum = cityNum * (cityNum - 1) / 2;
        for (int i = 0; i < roadNum; ++i) {
            cin >> road[i].from >> road[i].to >> road[i].distance;
        }

        cout << Kruskal(cityNum, roadNum) << endl;
    }
    return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-24 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
去B座二楼砸水泥地:不过也可以理解,这种应该没参加过秋招
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务