zoukankan      html  css  js  c++  java
  • CCF CSP 数据中心

    题目

    试题编号: 201812-4
    试题名称: 数据中心
    时间限制: 1.0s
    内存限制: 512.0MB
    问题描述:
    在这里插入图片描述
    在这里插入图片描述

    样例输入

    4
    5
    1
    1 2 3
    1 3 4
    1 4 5
    2 3 8
    3 4 2

    样例输出

    4

    样例说明

    下图是样例说明。
    在这里插入图片描述
    在这里插入图片描述

    分析

    虽然题目说的很复杂,但是仔细观察样例后发现,其实就是一个最小生成树的问题,甚至都不需要考虑根节点在什么位置,因为无论在什么位置,只要把最小生成树求出来,问题就是符合题目要求的。

    代码

    代码1:写cmp函数,不使用容器

    #include <bits/stdc++.h>
    using namespace std;
    
    #define MAX 100001
    #define MAXN 500001
    
    struct Edge{
        int u;
        int v;
        int w;
        Edge(){};
        Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
    };
    
    int pre[MAXN];
    Edge edge[MAX];
    
    bool cmp(Edge e1, Edge e2){
        return e1.w < e2.w;
    }
    
    int find(int root){
        int tmp, son;
        son = root;
        while(root != pre[root]){
            root = pre[root];
        }
        while(son != root){
            tmp = pre[son];
            pre[son] = root;
            son = root;
        }
        return root;
    }
    
    bool join(int x, int y){
        int rootx = find(x);
        int rooty = find(y);
        if(rootx != rooty){
            pre[rootx] = rooty;
            return true;
        }
        return false;
    }
    
    int main(){
        int n = 0, m = 0, root = 0, i = 0, ans = 0, num = 0;
        cin >> n >> m >> root;
        for(i=0; i<n; i++){
            pre[i] = i;
        }
        for(i=0; i<m; i++){
            cin >> edge[i].u >> edge[i].v >> edge[i].w;
        }
        sort(edge, edge+m, cmp);
        for(i=0; i<m; i++){
            if(join(edge[i].u, edge[i].v)){
                ans = edge[i].w;
                num += 1;
                if(num == n-1){
                    break;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    

    代码2:重载 < 运算符,不使用容器

    #include <bits/stdc++.h>
    using namespace std;
    
    #define MAX 100001
    #define MAXN 500001
    
    struct Edge{
        int u;
        int v;
        int w;
        Edge(){};
        Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
        bool operator < (struct Edge &e1){
            return this->w < e1.w;
        }
    };
    
    int pre[MAXN];
    Edge edge[MAX];
    
    int find(int root){
        int tmp, son;
        son = root;
        while(root != pre[root]){
            root = pre[root];
        }
        while(son != root){
            tmp = pre[son];
            pre[son] = root;
            son = root;
        }
        return root;
    }
    
    bool join(int x, int y){
        int rootx = find(x);
        int rooty = find(y);
        if(rootx != rooty){
            pre[rootx] = rooty;
            return true;
        }
        return false;
    }
    
    int main(){
        int n = 0, m = 0, root = 0, i = 0, ans = 0, num = 0;
        cin >> n >> m >> root;
        for(i=0; i<n; i++){
            pre[i] = i;
        }
        for(i=0; i<m; i++){
            cin >> edge[i].u >> edge[i].v >> edge[i].w;
        }
        sort(edge, edge+m, cmp);
        for(i=0; i<m; i++){
            if(join(edge[i].u, edge[i].v)){
                ans = edge[i].w;
                num += 1;
                if(num == n-1){
                    break;
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    
    

    代码3:重载 < 运算符,使用容器

    #include <bits/stdc++.h>
    using namespace std;
    
    struct Edge{
        int u;
        int v;
        int w;
        Edge(){}
        Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
        bool operator < (struct Edge &e1){
            return this->w < e1.w;
        }
    };
    
    const int maxn = 500001;
    const int maxm = 100001;
    int pre[maxn];
    vector<Edge> edge;
    
    int findx(int root){
        int son, tmp;
        son = root;
        while(root != pre[root]){
            root  = pre[root];
        }
        while(son != root){
            tmp = pre[son];
            pre[son] = root;
            son = tmp;
        }
        return root;
    }
    
    int join(int root1, int root2){
        int x = findx(root1);
        int y = findx(root2);
        if(x != y){
            pre[x] = y;
            return true;
        }
        return false;
    }
    
    int main(){
        int n = 0, m = 0, i = 0, ans = 0, num = 0, root = 0;
        int tmp1, tmp2, tmp3;
        cin >> n >> m >> root;
        for(i=0; i<m; i++){
            cin >> tmp1 >> tmp2 >> tmp3;
            edge.push_back(Edge(tmp1, tmp2, tmp3));
        }
        for(i=0; i<n; i++){
            pre[i] = i;
        }
        sort(edge.begin(), edge.end());
        for(vector<Edge>::iterator it = edge.begin(); it != edge.end(); it++){
            if(join(it->u, it->v)){
                ans = it->w;
                num++;
                if(num == n-1){
                    cout << ans;
                    break;
                }
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    逻辑思维杂想
    C++二叉树实现
    斐波那数列递归实现与动态规划实现
    C++双向链表的实现
    C++单链表实现
    C++顺序表实现
    windows下端口占用处理工具
    [项目记录]一个.net下使用HAP实现的吉大校园通知网爬虫工具:OAWebScraping
    [c++]大数运算---利用C++ string实现任意长度正小数、整数之间的加减法
    [C++]几种排序
  • 原文地址:https://www.cnblogs.com/wlglucky/p/12458736.html
Copyright © 2011-2022 走看看