NOIp模拟 电缆建设

【问题描述】
教主上电视了,但是蔚蓝城郊区沿河的村庄却因电缆线路老化而在直播的时
候停电,这让市长SP先生相当的愤怒,他决定重修所有电缆,并改日播放录像,
杜绝此类情况再次发生。
河流两旁各有n,m个村庄,每个村庄可以用二维坐标表示,其中河流一旁的
村庄横坐标均为x1,河流另一旁的村庄横坐标均为x2。由于地势十分开阔,任意
两个村庄可以沿坐标系直线修建一条电缆连接,长度即为两村庄的距离。要修建
若干条电缆,使得任意两个村庄都可以通过若干个有电缆连接的村庄相连。
因为修建的经费与长度成正比,SP市长当然希望所花的钱越少越好,所以他
希望你来帮助他设计一套方案,使得电缆总长度最小,并告诉所需要的电缆总长
度。
【输入格式】
输入的第1行为四个正整数,n,m,x1,x2,表示河流两旁的村庄数以及横坐
标。
第2行有n个正整数y1[1], y1[2]... y1[n],描述了横坐标为x1的村庄的纵坐标。第1
个整数为纵坐标最小的那个村庄的纵坐标,从第2个整数开始,第i个整数代表当
前村庄与前一个村庄的纵坐标差,即y[i]-y[i-1]。
第3行有m个正整数y2[1], y2[2]... y2[n],用同样的方法描述了横坐标为x2的村庄
的纵坐标。
【输出格式】
输出仅包括一个实数,为最小的总长度,答案保留两位小数。
【样例输入】
2 3 1 3
1 2
2 2 1
【样例输出】
7.24
【样例解释】
按如下方案建设电缆,括号内代表村庄的坐标,“-”代表有电缆连接。
(1,1)-(1,3)
(1,3)-(3,4)
(3,4)-(3,2)
(3,4)-(3,5)
【数据规模】
对于20%的数据,n,m≤10;
对于40%的数据,n,m≤1000;
对于70%的数据,n,m≤100000;
对于100%的数据,n,m≤600000,所有村庄纵坐标不超过10^8,x1<x2<2000,

输入文件不超过4M。

难点:建图。

一看就是mst,但是这个数据比较大。

不能无脑加边。

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 666666
#define LL long long
using namespace std;
LL n,m,x1,x2,a[N],b[N],f[N*2];
LL cnt=0;
double ans=0;
struct Edge{
    int u,v;
    double dist;
}e[N*10];
int findf(int x){
    if (f[x]!=x) f[x]=findf(f[x]);
    return f[x];
}
bool cmp(Edge a,Edge b){
    return a.dist <b.dist;
}
double calc(int k1,int k2){
    return sqrt((double)(x1-x2)*(x1-x2)+(a[k1]-b[k2])*(a[k1]-b[k2]));
}
void init(){
    scanf("%d%d%d%d",&n,&m,&x1,&x2);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        a[i]+=a[i-1];
        f[i]=i;
    }
    for (int i=1;i<=m;i++)
    {
        scanf("%d",&b[i]);
        b[i]+=b[i-1];
        f[i+n]=i+n;
    }
    int id=1;
    for(int i=1;i<=n;i++)
    {
        if (i!=n) e[++cnt]=(Edge) {i,i+1,a[i+1]-a[i]};
        while (id<m && calc(i,id) > calc(i,id+1)) id++;//找河对面与i点最近的
        e[++cnt]=(Edge) {i,id+n,calc(i,id)};
        if (id>1) e[++cnt]=(Edge) {i,id-1+n,calc(i,id-1)};
        if (id<m) e[++cnt]=(Edge) {i,id+1+n,calc(i,id+1)};
        /*离i点最近的及其相邻的b村庄的点加入边集数组*/
    }
    for (int i=1;i<=m;i++)
        if (i!=m) e[++cnt]=(Edge) {i+n,i+n+1,b[i+1]-b[i]};
}
void kruskal(){
    sort(e+1,e+cnt+1,cmp);
    int rst=n+m;
    for (int i=1;i<=cnt && rst>1;i++)
    {
        int x=findf(e[i].u);
        int y=findf(e[i].v);
        if (x!=y)
        {
            f[x]=f[y];
            rst--;
            ans+=e[i].dist;
        }
    }
    printf("%.2lf",ans);
}
int main(){
    //freopen("cable.in","r",stdin);
	//freopen("cable.out","w",stdout);
    init();
    kruskal();
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值