zoukankan      html  css  js  c++  java
  • 九度 1347:孤岛连通工程(最小生成树)

    总结

    1. Objects in a set are immutable; if you want to modify an object, you need to:

    a. make a copy of the object from the set

    b. modify the copy

    c. remove the original object from the object, and

    d. insert the copy into the set

    2. Each associative container is parameterized on Key and an ordering relation Compare that induces a strict weak ordering on elements of Key

    3. Two key k1 and k2 are cosideraed to be equivalent if for the comparision object comp, comp(k1, k2) == false && comp(k2, k1) == false

    strict weak order 要求让比较函数对相等的值返回 false

    4. 这道题使用 STL SET 实属画蛇添足, 因为 SET 自定义类型的比较函数难以定义. 在下面的代码中, SET 仅将 i==j==cost 的点视为相同 

    题目描述:

    现在有孤岛n个,孤岛从1开始标序一直到n,有道路m条(道路是双向的,如果有多条道路连通岛屿i,j则选择最短的那条),请你求出能够让所有孤岛都连通的最小道路总长度。

    思路

    1. 求解最小耗费树

    2. 最小耗费树的算法有 Prim算法和 Kruskal 算法, 两者皆为贪心算法

    Prim 算法扩展当前树, Kruskal 每次加入耗费最小的安全边

    3. Prim 算法需要 priority_queue, Kruskal 算法需要使用并查集, 一般来说还是 Kruskal 算法易于实现

    代码 使用了 STL SET 导致超时, 不过案例均 AC

    #include <iostream>
    #include <stdio.h>
    #include <set>
    #include <memory.h>
    using namespace std;
    
    int n, m;
    int father[10100];
    
    class Edge {
    public:
        int i, j, cost;
    
        Edge(int _i, int _j, int _cost):i(_i), j(_j), cost(_cost) {}
        Edge() {
            Edge(0, 0, 0);
        }
        bool operator<(const Edge &ths) const {
            if(this->cost == ths.cost) {
                if(this->i == ths.i) {
                    return this->j < ths.j;
                }
                return this->i < ths.i;
            }
            return this->cost < ths.cost;
        }
    };
    
    int myFind(int x) {
        if(x == father[x])
            return x;
        else {
            father[x] = myFind(father[x]);
        }
        return father[x];
    }
    
    bool merge(int a, int b) {
        int fa = myFind(a);
        int fb = myFind(b);
    
        if(fa == fb)
            return false;
    
        father[fa] = fb;
        return true;
    }
    
    int main() {
        freopen("testcase.txt", "r", stdin);
        while(scanf("%d%d", &n, &m) != EOF) {
            set<Edge> edges;
            for(int i = 1; i <= n; i ++)
                father[i] = i;
    
            
            for(int k = 0; k < m; k ++) {
                int i, j, cost;
                scanf("%d%d%d", &i, &j, &cost);
                Edge newEdge(i, j, cost);
    
                if(edges.count(newEdge)) {
                    int oldcost = edges.find(newEdge)->cost;
                    edges.erase(edges.find(newEdge));
                    newEdge.cost = min(oldcost, newEdge.cost);
                }
    
                edges.insert(newEdge);
                
            }
    
            set<Edge>::iterator it_set;
            int res = 0;
            for(it_set = edges.begin(); it_set != edges.end(); it_set ++) {
                int i = it_set->i;
                int j = it_set->j;
                int cost = it_set->cost;
    
                if(merge(i, j)) {
                    res += cost;
                }
            }
    
            int visited = 0;
            for(int i = 1; i <= n; i ++) {
                if(i == father[i])
                    visited ++;
            }
    
            if(visited == 1)
                cout << res << endl;
            else
                cout << "no" << endl;
        }
        return 0;
    }
  • 相关阅读:
    Shell中的特殊变量和结构
    自由的Debian
    关于系统定制的一些链接
    超出两行显示省略号
    json转换
    区分LocalStorage和偏好数据
    去除谷歌浏览器中的默认文本框样式
    js访问xml
    js执行跨域请求
    mvc通过controller创建交互接口
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3592102.html
Copyright © 2011-2022 走看看