zoukankan      html  css  js  c++  java
  • Built?

    There are N towns on a plane. The i-th town is located at the coordinates (xi,yi). There may be more than one town at the same coordinates.
    You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|a−c|,|b−d|) yen (the currency of Japan). It is not possible to build other types of roads.
    Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?

    Constraints
    2≤N≤105
    0≤xi,yi≤109
    All input values are integers.

    输入

    Input is given from Standard Input in the following format:

    N
    x1 y1
    x2 y2
    :
    xN yN

    输出

    Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.

    样例输入

    3
    1 5
    3 9
    7 8

    样例输出
    3 

    提示

    Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.

    这个题目大致意思就是给了n个点的坐标,最终目的是这N个点两两可以走到,两个点的权值是min(fabs(x1-x2),fabs(y1-y2));

    这其实就是就是一个最小生成树的变形;

    因为一个点只会和离他最近的两个点进行连接,所以要分别按照x和Y进行排序,从而确定权值,然后再用并查集原理解决就好了;

    下面是AC代码

    #include <bits/stdc++.h>
    using namespace std;
    //#define mod 1000000007
    int fa[110000];
    typedef struct
    {
        int x,y,hao;//x坐标,y坐标,和对应序号
    }qq;
    typedef struct
    {
        int p1,p2,p3;//分别是两个点之间的距离和,两个点所对应标号
    }pp;
    bool cmp1(qq r,qq t)
    {
        return r.x<t.x;//按照X排序
    }
    bool cmp2(qq r,qq t)
    {
        return r.y<t.y;//按照y排序
    }
    bool cmp3(pp r,pp t)
    {
        return r.p1<t.p1;//最后的路径的权值排序
    }
    int getfa(int a)//找父节点的函数
    {
        if(fa[a]!=a)
        {
            return fa[a]=getfa(fa[a]);
        }
        else
        {
            return a;
        }
    }
    qq a[110000];
    pp b[440000];
    int main()
    {
        int n;
         scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            fa[i]=i;
        }
     for(int i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].hao=i;
        }
        sort(a,a+n,cmp1);
        int k=0;
        for(int i=1;i<n;i++)
        {
           b[k].p1=a[i].x-a[i-1].x;
           b[k].p2=a[i].hao;
           b[k].p3=a[i-1].hao;
           k++;
        }
        sort(a,a+n,cmp2);
        for(int i=1;i<n;i++)
        {
            b[k].p1=a[i].y-a[i-1].y;
            b[k].p2=a[i].hao;
            b[k].p3=a[i-1].hao;
            k++;
        }
        sort(b,b+2*n-2,cmp3);
        long long int s=0;//要用long long int 
        for(int i=0;i<2*n-2;i++)
        {
            if(getfa(b[i].p2)!=getfa(b[i].p3))
            {
                s+=b[i].p1;
                fa[getfa(b[i].p3)]=getfa(b[i].p2);
            }
        }
        printf("%lld
    ",s);
        return 0;
    }
  • 相关阅读:
    Learn Orleans 04
    Learn Orleans 03
    Learn Orleans 02
    Learn Orleans 01
    Python 导入 Excel 到数据库
    visio 2016/2019 时序图/序列图,修改消息的实线/虚线 箭头问题 返回消息状态
    steeltoe简单使用
    AOP in .NET
    centos 8 docker安装以及兼容性问题处理
    ef core SoftDelete Multi-tenancy 软删除、多租户实现 Global Query Filters
  • 原文地址:https://www.cnblogs.com/xiaolaji/p/9274041.html
Copyright © 2011-2022 走看看