HDU 1162 Eddy's picture(最小生成树-Prim)

本文介绍了一种计算多个点间最短线段长度的方法,通过最小生成树算法实现,适用于多组不同点集的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description
给出n个点,用最短的线段将这些点连起来,输出最短长度
Input
多组输入,每组用例第一行为点数n,之后n行每行两个浮点数表示该点横纵坐标,以文件尾结束输入
Output
对于每组用例,输出最短线段长度,结果保留小数点后两位
Sample Input
3
1.0 1.0
2.0 2.0
2.0 4.0
Sample Output
3.41
Solution
最小生成树裸题,套Prim或者Kruskal模版均可
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 111
double cost[maxn][maxn];//cost[u][v]表示的是边e=(u,v)的权值(不存在的时候设为INF)
double mincost[maxn];//从集合X出发的边到每个顶点的最小权值
bool used[maxn];//顶点i是否包含在集合X中
int V;//顶点数
double prim()
{
    for(int i=0;i<V;i++)//初始化 
    {
        mincost[i]=cost[0][i];
        used[i]=false;
    }
    used[0]=true;//把第一个顶点加进集合X中 
    double res=0.0; 
    for(int i=1;i<V;i++)
    {
        int v=-1;
        double minc=1.0*INF;
        for(int u=0;u<V;u++)//从不属于集合X的顶点中选取从X到其权值最小的顶点 
            if(!used[u]&&mincost[u]<minc)
                v=u,minc=mincost[u];
        if(v==-1)break;
        used[v]=true;//把顶点v加到集合X中
        res+=minc;//把边权加到结果中 
        for(int u=0;u<V;u++)//mincost中始终存的是集合X中元素到每个顶点的最小权值 
            mincost[u]=min(mincost[u],cost[u][v]); 
    }
    return res;
} 
struct node
{
    double x,y;
}p[maxn];
double dis(node a,node b)//两点间距离 
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
    while(~scanf("%d",&V))
    {
        for(int i=0;i<V;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i=0;i<V;i++)//注意初始化 
            cost[i][i]=INF;
        for(int i=0;i<V;i++)
            for(int j=i+1;j<V;j++)
                cost[j][i]=cost[i][j]=dis(p[i],p[j]);
        double ans=prim(); 
        printf("%.2lf\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值