zoukankan      html  css  js  c++  java
  • justoj connect(边的处理)

    CONNECT

    https://oj.ismdeep.com/contest/problem?id=1702&pid=2

    Problem Description

    有nn个顶点,每个顶点有自己的坐标(Xi,Yi,Zi)(Xi,Yi,Zi),现在想把这nn个顶点连接起来,已知连接两个顶点uu和vv的花费是MIN(|Xu−Xv|,|Yu−Yv|,|Zu−Zv|) 。现在,请花费最小的代价把这些点连接起来。

    Input

    第一行输入一个整数n (1≤n≤2∗105)n (1≤n≤2∗105)

    接下来nn行,第ii行包含33个整数XiXi,YiYi和ZiZi(|Xi|,|Yi|,|Zi|≤109)(|Xi|,|Yi|,|Zi|≤109),代表第ii个点的坐标,数据保证不会有任意两个点的坐标相同

    Output

    输出最小代价

    Sample Input

    3
    1 1 1
    2 3 4
    5 5 5
    

    Sample Output

    2
    

    思路:本质是最小生成树。需要对边进行处理。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 200000 + 5;
    
    struct Edge
    {
        ll u,v,dis;
    };
    
    struct Point
    {
        ll x,y,z,index;
    };
    Edge edge[maxn*3];
    Point point[maxn];
    
    int fa[maxn];
    ll edgenum;
    ll res;
    
    bool cmpx(Point a,Point b)
    {
        return a.x<b.x;
    }
    
    bool cmpy(Point a,Point b)
    {
        return a.y<b.y;
    }
    
    bool cmpz(Point a,Point b)
    {
        return a.z<b.z;
    }
    
    bool cmpdis(Edge a,Edge b)
    {
        return a.dis<b.dis;
    }
    
    int find(int x)
    {
        while(x!=fa[x])
        x=fa[x]=fa[fa[x]];
        return x;
    }
    
    int main() 
    {
        ll n;
        scanf("%lld",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%lld%lld%lld",&point[i].x,&point[i].y,&point[i].z);
            point[i].index=i;
        }
        edgenum=0;
        sort(point,point+n,cmpx);
        for(int i=0;i<n-1;i++)
        {
            edge[edgenum].u=point[i+1].index;
            edge[edgenum].v=point[i].index;
            edge[edgenum].dis=point[i+1].x-point[i].x;
            edgenum++;
        }
        sort(point,point+n,cmpy);
        for(int i=0;i<n-1;i++)
        {
            edge[edgenum].u=point[i+1].index;
            edge[edgenum].v=point[i].index;
            edge[edgenum].dis=point[i+1].y-point[i].y;
            edgenum++;
        }
        sort(point,point+n,cmpz);
        for(int i=0;i<n-1;i++)
        {
            edge[edgenum].u=point[i+1].index;
            edge[edgenum].v=point[i].index;
            edge[edgenum].dis=point[i+1].z-point[i].z;
            edgenum++;
        }
        sort(edge,edge+edgenum,cmpdis); //把每条边从小到大排
    
        for(int i=0;i<n;i++)
        fa[i]=i;
        int eu,ev,cnt=0;
        for(int i=0;i<edgenum;i++)
        {
            eu=find(edge[i].u);
            ev=find(edge[i].v);
            if(eu!=ev){
            fa[ev]=eu;
            res+=edge[i].dis;
            cnt++;
            }
            if(cnt==n-1) break;
        }
        printf("%lld
    ",res);
        return 0;
    }
    
  • 相关阅读:
    python3
    python2
    python的爬虫
    SQL SEVERE 基本用法 1
    安装SQL SEVER 2017 express 轻量入门级软件 安装教程
    面试学习资料
    后端架构师--总结网址收藏(个人)
    JVM学习网址(收集总结)
    RabbitMQ--学习资源汇
    Redis 学习资料目录(Important)
  • 原文地址:https://www.cnblogs.com/chilkings/p/11946628.html
Copyright © 2011-2022 走看看