zoukankan      html  css  js  c++  java
  • [暑假集训]数据结构&简单图论专题1 Eddy's picture

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <climits>
    #include <algorithm>
    using namespace std;
    int n;
    typedef struct{//边单元
        int from ;
        int to;
        double w;//长度
    }node;
    typedef struct{ double x , y;}coordinate;//点单元
    vector<coordinate>datas;//所有的点
    vector<node>edge;//所有的边
    int head[120];
    double lowc[120];
    int vis[120];
    void init(){
        datas.clear();
        edge.clear();
        for(int i = 0; i < 120; i ++){
            vis[i] = 0;
            lowc[i] = INT_MAX;
            head[i] = -1;
        }
    }
    bool cmp(node a , node b){//比较两边
        if(a.from == b.from && a.to == b.to) return a.w < b.w ;
        if(a.from == b.from) return a.to < b.to ;
        return a.from < b.from ;
    }
    double dist(coordinate a , coordinate b){
        double x = a.x - b.x ;
        double y = a.y - b.y ;
        return sqrt(x*x + y*y);
    }
    void input(){
        coordinate temp;
        for(int i = 0; i < n; i ++){
            scanf("%lf%lf",&temp.x , &temp.y);
            datas.push_back(temp);
        }
        node temp1;
        for(int i = 0; i < n; i ++)
        for(int j = i + 1; j < n; j ++){
            temp1.from = i;
            temp1.to = j;
            temp1.w = dist(datas[i] , datas[j]);
            edge.push_back(temp1);
            temp1.from = j;
            temp1.to = i;//添加所有可能的边
            edge.push_back(temp1);
        }
        sort(edge.begin() , edge.end() , cmp);//排序
        //以 from - to - 长度 依次比较
        head[0] = 0;
        for(int i = 1; i < (int)edge.size(); i ++){
            if(edge[i].from != edge[i-1].from){
                head[edge[i].from] = i;
            }
        }//记录以某一点为from的边在edge里第一次出现的地方。
    }
     
    double prim(){
        double res = 0;
        for(int i = head[0]; edge[i].from == 0 && i < n; i ++){
            lowc[edge[i].to] = edge[i].w ;
        }//lowc表示以一点到i点最短边长度
        vis[0] = 1;//0点已放入lowc
        int u ;
        double minc ;
        for(int i = 1; i < n; i ++){
            minc = INT_MAX;
            for(int j  = 0; j < n; j ++){
                if(!vis[j] && lowc[j] < minc ){
                    minc = lowc[j];//记录lowc里从某点出发最小边长度
                    u = j;//记录另一点的序号
                }
            }
            if(minc == INT_MAX) return -1;
            res += minc ;
            vis[u] = 1;
            for(int j = head[u]; edge[j].from == u && j < (int)edge.size(); j ++){
                //以u为开头的所有边
                if(!vis[edge[j].to] && lowc[edge[j].to] > edge[j].w){
                    //如果出现比之前记录的lowc更短的
                    lowc[edge[j].to] = edge[j].w;
                }
            }
     
        }
        return res;
    }
    int main(){
        while(scanf("%d",&n)!=EOF){
            init();
            input();
            printf("%.2lf
    ",prim());
        }
        return 0;
    }

    https://vjudge.net/contest/384914#problem/B

  • 相关阅读:
    jmeter如何监控服务器CPU、内存、i/o等资源
    Red hat下搭建简易实用的SVN服务器
    ICPC2021(济南)打星队线上打铁游记
    「笔记」如何优雅的造数据
    软件开发中,不要把重点放在“雕琢”上
    对公司数据库管理的看法
    工作两年来 对VB开发的感想
    对数学的一点认识
    学习面向对象语言的感受
    中国 奥运 加油!
  • 原文地址:https://www.cnblogs.com/forwhat00/p/13392478.html
Copyright © 2011-2022 走看看