洛谷P1265 公路修建 题解

P1265 公路修建

前面题目给的一大堆修建条件其实可以忽略,对做题没有什么影响。

读完题目后,很容易就能发现这是一道最小生成树的题目,可以使用Prim或Kruskal来求解,不过在一看数据,好家伙,完全图,这肯定得用Prim啊。

不用说,先输入。

接下来,分析Prim。sum用来记录最终答案,dis数组用来保存当前节点至其他未经过的点的最短距离,vis数组保存已经过的点。

先进行初始化,起始点当然为1号城市,先用欧几里得距离计算公式计算出1号城市与其他城市之间的距离,同时,vis[1]也要置为1。

初始化后,循环n-1次,每次寻找其他未遍历过的节点中和当前节点距离最短的节点,将它标记为1,并将这条边的长度加到总长度中,以此节点为当前节点,继续循环。

这就是这道题的解题思路,最后上代码。

#include<bits/stdc++.h> 
using namespace std;
struct node{
	double x,y;
}a[5010];
int n;
bool vis[5010];
double dis[5010];
double prim(){
	double sum=0;
	vis[1]=1;
	for(int i=2;i<=n;i++){
		dis[i]=sqrt((a[1].x-a[i].x)*(a[1].x-a[i].x)+(a[1].y-a[i].y)*(a[1].y-a[i].y));
	}
	dis[0]=1e9;
	for(int i=1;i<n;i++){
		int k=0;
		for(int j=1;j<=n;j++){
			if(!vis[j]&&dis[j]<dis[k]){
				k=j;
			}
		}
		vis[k]=1;
		sum+=dis[k];
		for(int j=1;j<=n;j++){
			double d=sqrt((a[k].x-a[j].x)*(a[k].x-a[j].x)+(a[k].y-a[j].y)*(a[k].y-a[j].y));
			if(!vis[j]&&dis[j]>d){
				dis[j]=d;
			}
		}
	}
	return sum;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lf %lf",&a[i].x,&a[i].y);
	}
	printf("%.2lf",prim());
	return 0;
}

如果有什么不足,还请大佬们指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值