HDU 4463 Outlets 最小生成树

Posted 00isok

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4463 Outlets 最小生成树相关的知识,希望对你有一定的参考价值。

<题目链接>

题目大意:

给你一些点的坐标,要求你将这些点全部连起来,但是必须要包含某一条特殊的边,问你连起这些点的总最短距离是多少。

解题分析:

因为一定要包含那条边,我们就记录下那条边的边权,然后将那条边边权置为0,再跑一遍最小生成树即可。

#include <cstdio>
#include <cmath> 
#include <cstring>
#include <algorithm>
using namespace std;

int n,s,e,cnt;
struct NODE{
    int x,y;
}node[55];
int father[55];
struct EDGE{
    int x,y;
    double val;
}edge[55*55];

bool cmp(EDGE a,EDGE b){
    return a.val<b.val;
}
double dis(NODE a,NODE b){
    return (double)sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)*1.0);
}
int find(int x){
    if(father[x]==x)return x;
    father[x]=find(father[x]);
    return father[x];
}
double Kruscal(){
    double sum=0;
    int num=0;
    for(int i=1;i<=n;i++)father[i]=i;
    sort(edge+1,edge+1+cnt,cmp);
    for(int i=1;i<=cnt;i++){
        int f1=find(edge[i].x),f2=find(edge[i].y);
        if(f1!=f2){
            father[f2]=f1;
            sum+=edge[i].val;
            num++;
        }
        if(num==n-1)break;
    }
    return sum;
}
int main(){
    while(scanf("%d",&n)!=EOF,n){
        scanf("%d%d",&s,&e);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&node[i].x,&node[i].y);
        }
        double ans=0;
        cnt=0;
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                edge[++cnt].x=i,edge[cnt].y=j,edge[cnt].val=dis(node[i],node[j]);
                if(i==s&&j==e||i==e&&j==s){
                    ans+=edge[cnt].val;    //记录下这条边的边权。然后将这条边边权置为0
                    edge[cnt].val=0;
                }
            }
        }
        ans+=Kruscal(); //跑一遍最小生成树
        printf("%.2lf
",ans);
    }
    return 0;
}

 

2018-10-07

以上是关于HDU 4463 Outlets 最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4463: Outlets

hdu 5253(最小生成树)

HDU1102 最小生成树prim算法

hdu1875(最小生成树prime)

HDU 5624 KK's Reconstruction(最小生成树)

HDU 4081 Peach Blossom Spring (最小生成树+dfs)