[最小生成树]剑鱼行动

来源:互联网 发布:淘宝取消实名认证 编辑:程序博客网 时间:2024/04/28 10:06

题目描述
给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数
Input
5 —————5个点
0 0 —————5个点的坐标
0 1
1 1
1 0
0.5 0.5
Output
2.83

分析
一道最小生成树的水题(要知最小生成树是什么,请见[最小生成树]USACO 3.1 Agri-Net 最短网络)
考点在于两点之间的距离要自己来求,并且不能用整数数组,以及——对我大C精度运算的考验

普里姆算法

#include <iostream>#include <cstdio>#include <cmath>using namespace std;int n,i,j,k,t;double r[101][2],a[101][101],ans,mi;bool f[101];int main (){    scanf("%d",&n);    for (i=1;i<=n;i++)        scanf("%lf%lf",&r[i][0],&r[i][1]);    for (i=1;i<=n;i++)     for (j=1;j<=n;j++)      a[i][j]=sqrt((r[i][0]-r[j][0])*(r[i][0]-r[j][0])+(r[i][1]-r[j][1])*(r[i][1]-r[j][1]));    f[1]=1;    for (k=1;k<=n-1;k++)    {        mi=2147483647;        for (i=1;i<=n;i++)            if (f[i])            for (j=1;j<=n;j++)                if (!f[j])                    if (a[i][j]<mi&&a[i][j]!=0)                    {                        mi=a[i][j];                        t=j;                    }        if (mi!=2147483647)        {            ans+=mi;            f[t]=1;        }    }    printf("%0.2lf",ans);}

克鲁斯卡尔算法

#include <iostream>#include <cstdio>#include <cmath>using namespace std;int n,i,j,k,q,p,t,f[101];double mi,ans,r[101][2],a[101][101];int main(){    scanf("%d",&n);    for (i=1;i<=n;i++)        scanf("%lf%lf",&r[i][0],&r[i][1]);    for (i=1;i<=n;i++)     for (j=1;j<=n;j++)      a[i][j]=sqrt((r[i][0]-r[j][0])*(r[i][0]-r[j][0])+(r[i][1]-r[j][1])*(r[i][1]-r[j][1]));    for (i=1;i<=n;i++) f[i]=i;    for (k=1;k<=n-1;k++)    {        mi=2147483647;        for (i=1;i<=n;i++)            for (j=1;j<=n;j++)                if (f[i]!=f[j]&&a[i][j]<mi&&a[i][j]!=0)                {                    mi=a[i][j];                    p=j;                    q=i;                }        ans+=mi;        t=f[p];        for (i=1;i<=n;i++) if (f[i]==t) f[i]=f[q];    }    printf("%0.2lf",ans);}
0 0
原创粉丝点击