• [暑假集训]数据结构&简单图论专题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

  • 相关阅读:
    Oracle基础 07 参数文件 pfile/spfile
    Oracle基础 06 控制文件 controlfile
    Oracle基础 05 联机日志 redolog
    Oracle基础 04 归档日志 archivelog
    Oracle基础 02 临时表空间 temp
    Oracle基础 03 回滚表空间 undo
    Oracle基础 01 表空间 tablespace
    PL/SQL Developer 连接 Oracle
    Windows下卸载Oracle
    Vue:基础语法
  • 原文地址:https://www.cnblogs.com/forwhat00/p/13392478.html
Copyright © 2020-2023  润新知