zoukankan      html  css  js  c++  java
  • 最小生成树

    问题 F: 修建道路 (roads)

    时间限制: 1 Sec  内存限制: 128 MB
    提交 状态

    题目描述

    Farmer John 最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达 (也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农场)。有些农场之间原本就有道路相连。

    所有N(1≤N≤1000个农场(用1...N顺次编号)在地图上都表示为坐标为(Xi,Yi)的点(0≤Xi≤1000000,0≤Yi≤1000000),两个农场间道路的长度自然就是代表它们的点之间的距离。

    现在 Farmer John 也告诉了你农场间原有的M(1≤M≤1000条路分别连接了哪两个农场, 他希望你计算一下,为了使得所有农场连通,他所需建造道路的最小总长是多少。

    输入

    第 1行: 2个用空格隔开的整数:N和 M
    第2...N+1  行:第i+1行为2个用空格隔开的整数:Xi,Yi
    第N+2...N+M+1行:每行用2个以空格隔开的整数i、j描述了一条已有的道路,这条道路连接了农场i和农场j

    输出

    第1行:输出使所有农场连通所需建设道路的最小总长,保留2位小数,不必做任何额外的取整操作。为了避免精度误差,计算农场间距离及答案时,请使用64位实型变量。

    样例输入 Copy

    4 1
    1 1
    3 1
    2 3
    4 3
    1 4
    

    样例输出 Copy

    4.00
    

    提示

    样例解释

    FJ 一共有4个坐标分别为 (1,1),(3,1),(2,3),(4,3)的农场。农场1和农场4之间原本就有道路相连。
    FJ 选择在农场1和农场2 间建一条长度为2.00的道路,在农场3和农场4间建一条长度为2.00的道路。这样,所建道路的总长为4.00,并且这是所有方案中道路总长最小的一种。

    对于所有的数据,1≤N,M≤1000,0≤Xi,Yi≤1000000
    #include<bits/stdc++.h> 
    #include <math.h>
    using namespace std;
    typedef long long ll; 
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int maxn=5e5+10;
    struct node{
        int x,y;
        double z;
    }a[maxn];
    double ans;
    int n,m,len,p;
    int x[maxn],y[maxn];
    int fa[maxn];
    bool cmp(node x,node y){
        return x.z<y.z;
    } 
    double di(int i,int j){
        double xx,yy;
        xx=(double)(x[i]-x[j]);
        yy=(double)(y[i]-y[j]);
        return sqrt(xx*xx+yy*yy);
    }
    int find(int h) 
    {    
        return fa[h]==h?h:fa[h]=find(fa[h]); 
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%d",&x[i]);
            scanf("%d",&y[i]);
        } 
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                a[++len].x=i;
                a[len].y=j;
                a[len].z=di(i,j);
            }
        }
        sort(a+1,a+len+1,cmp);
        for(int i=1;i<=n;i++){
            fa[i]=i;
        } 
        p=n;
        int s,t;
        for(int i=1;i<=m;i++){
            s=read();
            t=read();
            int diss=find(s);
            int dist=find(t);
            if(diss!=dist){
                p--;
                fa[dist]=diss;
            } 
        }
        for(int i=1;i<=len;i++){
            if(p==1){
                break;
            }
            int s=a[i].x;
            int t=a[i].y;
            int diss=find(s);
            int dist=find(t);
            if(diss!=dist){
                p--;
                fa[dist]=diss;
                ans+=a[i].z;
            }
        }
        printf("%.2lf",ans); 
    } 
  • 相关阅读:
    poj 3040 Allowance
    poj 2393 Yogurt factory
    【BZOJ1833】数字计数(ZJOI2010)-数位DP
    【BZOJ4820】硬币游戏(SDOI2017)-概率+高斯消元+KMP
    【BZOJ3626】LCA(LNOI2014)-树链剖分+离线处理
    【BZOJ4817】树点涂色(SDOI2017)-LCT+LCA+线段树
    【BZOJ1135】LYZ(POI2009)-线段树+Hall定理
    【CF392D】Three Arrays-set+multiset
    【51Nod1688】LYKMUL-线段树+乘法原理
    【BZOJ2956】模积和-数论分块
  • 原文地址:https://www.cnblogs.com/lipu123/p/13284957.html
Copyright © 2011-2022 走看看