zoukankan      html  css  js  c++  java
  • 51nod 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

    裸最小生成树

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <iomanip>
    #include <math.h>
    #include <map>
    using namespace std;
    #define FIN     freopen("input.txt","r",stdin);
    #define FOUT    freopen("output.txt","w",stdout);
    #define INF     0x3f3f3f3f
    #define INFLL   0x3f3f3f3f3f3f3f
    #define lson    l,m,rt<<1
    #define rson    m+1,r,rt<<1|1
    typedef long long LL;
    typedef pair<int, int> PII;
    using namespace std;
    
    /*
    * Kruskal算法求MST
    */
    const int MAXN = 1000 + 5; //最大点数
    const int MAXM = 50000 + 5; //最大边数
    int F[MAXN];//并查集使用
    struct Edge {
        int u, v, w;
    } edge[MAXM]; //存储边的信息,包括起点/终点/权值
    int tol;//边数,加边前赋值为0
    void addedge(int u, int v, int w) {
        edge[tol].u = u;
        edge[tol].v = v;
        edge[tol++].w = w;
    }
    bool cmp(Edge a, Edge b) {
        //排序函数,讲边按照权值从小到大排序
        return a.w < b.w;
    }
    int find(int x) {
        if(F[x] == -1)return x;
        else return F[x] = find(F[x]);
    }
    int Kruskal(int n) { //传入点数,返回最小生成树的权值,如果不连通返回-1
        memset(F, -1, sizeof(F));
        sort(edge, edge + tol, cmp);
        int cnt = 0; //计算加入的边数
        int ans = 0;
        for(int i = 0; i < tol; i++) {
            int u = edge[i].u;
            int v = edge[i].v;
            int w = edge[i].w;
            int t1 = find(u);
            int t2 = find(v);
            if(t1 != t2) {
                ans += w;
                F[t1] = t2;
                cnt++;
            }
            if(cnt == n - 1)break;
        }
        if(cnt < n - 1)return -1; //不连通
        else return ans;
    }
    
    int main() {
        //FIN
        int n, m;
        while(~scanf("%d%d", &n, &m)) {
            tol = 0;
            for(int i = 1; i <= m; i++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                addedge(u, v, w);
            }
            int ans = Kruskal(n);
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    关于C语言中的绝对值函数
    B. Interesting drink(水题 二分)
    A. Boring Apartments(水题)
    A. FashionabLee(水题)
    A. Collecting Coins(水题)
    A. Fancy Fence(水题)
    最小公因数,最小公倍数,以及快速幂模板
    android:layout_gravity 和 android:gravity 的区别
    Android开发之Intent略解
    java中类的创建及初始化过程
  • 原文地址:https://www.cnblogs.com/Hyouka/p/7448176.html
Copyright © 2011-2022 走看看