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

来源:互联网 发布:pcb里怎么筛选相同网络 编辑:程序博客网 时间:2024/06/05 18:10

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 111double 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;}
0 0
原创粉丝点击