洛谷 P1265 公路修建 题解

1 题面

公路修建

2 分析

这题特别的地方就是边多, 5000 × 5000 5000\times 5000 5000×5000的边用kruscal空间不对.
主要空间瓶颈就是边的权是存不下来的,然而kruscal是需要计算然后再sort一遍的,我们想到prim.
其实prim算法我没有怎么选过,这题就当作prim练习题叭QAQ

3 具体实现

prim的主要思想就是对于已联通的点集 u u u与未联通的点集 v v v之间的所有边,选择一个最小的选上,这样就是最小的了.
那为什么这样是对的呢?
这里给出一个感性证明:对于每次选择,都将一个新点加入点集 u u u中,我们知道每个点都是要进入 u u u中的,而我们的算法又选的是最小的边,那么整个生成树一定就是最小的.

解释一下变量的意思:
pos代表从 u u u v v v新加入的那个点
vis[i]代表i是否在点集 u u u
ans是最小生成树的大小
//dis是这一题要求的距离

void prim(){
    int pos=0;
    for (int i=1; i<=n; i++) {
        double minx=inf;
        for (int j=1; j<=n; j++) {
            if (!vis[j] && dis[j]<minx) {
                minx=dis[j];
                pos=j;
            }
        }
        ans+=minx;
        vis[pos]=1;
        for (int j=1; j<=n; j++) {
            double d=cal(pos, j);
            dis[j]=std::min(dis[j],d);
        }
    }
}

4 参考代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#define inf 99999999.0
#define maxn 5001
int n;
double dis[maxn],ans;
bool vis[maxn];
struct node{
    int x,y;
}nodes[maxn];
double cal(int i,int j){
    return sqrt((double)(nodes[i].x-nodes[j].x)*(nodes[i].x-nodes[j].x)+(double)(nodes[i].y-nodes[j].y)*(nodes[i].y-nodes[j].y));
}
void prim(){
    int pos=0;
    for (int i=1; i<=n; i++) {
        double minx=inf;
        for (int j=1; j<=n; j++) {
            if (!vis[j] && dis[j]<minx) {
                minx=dis[j];
                pos=j;
            }
        }
        ans+=minx;
        vis[pos]=1;
        for (int j=1; j<=n; j++) {
            double d=cal(pos, j);
            dis[j]=std::min(dis[j],d);
        }
    }
}
int main(){
    scanf("%d",&n);
    for (int i=1; i<=n; i++) {
        scanf("%d%d",&nodes[i].x,&nodes[i].y);
        dis[i]=inf;
    }
    dis[1]=0;
    prim();
    printf("%.2lf\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值