• 51nod_1212_无向图最小生成树(模板题)


    1212 无向图最小生成树

    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
     
    N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
     
    Input
    第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)
    第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
    Output
    输出最小生成树的所有边的权值之和。
    Input示例
    9 14
    1 2 4
    2 3 8
    3 4 7
    4 5 9
    5 6 10
    6 7 2
    7 8 1
    8 9 7
    2 8 11
    3 9 2
    7 9 6
    3 6 4
    4 6 14
    1 8 8
    Output示例
    37

    prim 每次向树中加一个点
    // prim
    #include <iostream>
    #include <algorithm>
    
    using namespace std; 
    
    
    #define maxn 1005 
    #define INF 99999999
    
    bool visit[maxn]; 
    int min_dis[maxn]; 
    int map_dis[maxn][maxn]; 
    
    int n, m;
    int s, e, w;
    
    int prim() {
        
        for (int i = 0; i < n; i++) {
            visit[i] = false; 
            min_dis[i] = INF; 
            
        }
        
        min_dis[0] = 0; 
        // visit[0] = true; 
        int sum = 0;
    
        
        while (true) {
            int pos = -1;
    
            for (int i = 0; i < n; i++) {
                if (!visit[i] && (pos == -1 || min_dis[i] < min_dis[pos])) {
                    pos = i;
                }
            }
    
            // cout << 1 << endl;
    
            if (pos == -1) {
                break; 
            }
            else {
    
                sum += min_dis[pos];
                //cout << "sum = " << sum << endl;
                //cout << "pos = " << pos << endl; 
            }
    
            visit[pos] = true;
    
            for (int i = 0; i < n; i++) {
                if (!visit[i] && map_dis[pos][i] < min_dis[i]) {
                    min_dis[i] = map_dis[pos][i];
                }
            }
        }
        return sum; 
    }
    
    int main() {
    
        while (cin >> n >> m) {
    
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    map_dis[i][j] = INF; 
                }
            }
    
            for (int i = 0; i < m; i++) {
                cin >> s >> e >> w;
                s -= 1; 
                e -= 1;
    
                map_dis[s][e] = w; 
                map_dis[e][s] = w; 
            }
    
            int result = prim(); 
    
            cout << result << endl; 
        }
        return 0; 
    }

    Kruskal 每次向树中加一条边

    // Kruskal 
    #include <iostream>
    #include <algorithm>
    
    using namespace std; 
    
    #define maxn 60000
    int father[maxn];
    int son[maxn]; 
    
    
    struct line {
        int a,
            b,
            value; 
    };
    
    // 边按权值大小排序
    bool cmp(line & a, line & b) {
        return a.value < b.value; 
    }
    
    int check_tree_root(int x) {
        // 递归找到 树根 并返回
        return x == father[x] ? x : check_tree_root(father[x]); 
    }
    
    // 检查 x 和 y 所在的两个树是否可以合并
    bool join(int x, int y) {
    
        int root1 = check_tree_root(x); 
        int root2 = check_tree_root(y); 
    
        // x 和 y 属于同一棵树
        if (root1 == root2) {
            return false; 
        }
        else {
            // 树根为 root1 的树规模较大
            if (son[root1] >= son[root2]) {
                father[root2] = root1; 
                son[root1] += son[root2]; 
            }
            else {
                father[root1] = root2; 
                son[root2] += son[root1]; 
            }
        }
    
        return true; 
    }
    
    int main() {
        
        int v, e; 
    
        line node[maxn]; 
    
        cin >> v >> e; 
    
        for (int i = 0; i < e; i++) {
            cin >> node[i].a >> node[i].b >> node[i].value; 
        }
    
        for (int i = 0; i <= v; i++) {
            // 初始情况 每个单独的节点都是一颗树
            // 树根是自己本身 , 树的节点数 为 1 
            father[i] = i; 
            son[i] = 1; 
        }
    
        sort(node, node + e, cmp); 
        
        int sum_e = 0; 
        int sum = 0; 
        bool flag = false; 
    
        for (int i = 0; i < e; i++) {
            // 如果可以加边
            if (join(node[i].a, node[i].b)) {
                sum_e++; 
                sum += node[i].value; 
            }
    
            if (sum_e == v - 1) {
                flag = true; 
                break; 
            }
        }
    
        if (flag == true) {
            cout << sum << endl;
        }
        
        return 0; 
    }
  • 相关阅读:
    Kotlin 数据类与密封类
    Kotlin 扩展
    Kotlin 接口
    Kotlin 继承
    Kotlin 类和对象
    Kotlin 循环控制
    Kotlin 条件控制
    Kotlin 基础语法
    freemarker的简单入门程序
    json数据格式的简单案例
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/9425510.html
Copyright © 2020-2023  润新知