POJ 2560 Freckles(最小生成树-Kruskal)

来源:互联网 发布:大数据产业园怎么样 编辑:程序博客网 时间:2024/05/16 17:44

Description
给出n个点的坐标,求把所有点连起来的最短距离
Input
第一行为一整数n表示点数,之后n行每行两个浮点数表示该点横纵坐标(1<=n<=100)
Output
输出把所有点连起来的最短距离
Sample Input
3
1.0 1.0
2.0 2.0
2.0 4.0
Sample Output
3.41
Solution
最小生成树裸题
Code

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>using namespace std;#define maxn 111struct edge{    int u,v;    double cost;};struct node{    double x,y;}p[maxn];edge es[maxn*maxn];int E,V; int par[maxn];int rank[maxn];bool comp(const edge&e1,const edge&e2){    return e1.cost<e2.cost;}void init(int n){    for(int i=0;i<n;i++)    {        par[i]=i;        rank[i]=0;    }}int find(int x){    if(par[x]==x) return x;    return par[x]=find(par[x]);}void unite(int x,int y){    x=find(x);    y=find(y);    if(x==y) return ;    if(rank[x]<rank[y]) par[x]=y;    else    {        par[y]=x;        if(rank[x]==rank[y]) rank[x]++;    }}bool same(int x,int y){    return find(x)==find(y);}double kruskal(){    sort(es,es+E,comp);    init(V);    double res=0;    for(int i=0;i<E;i++)    {        edge e=es[i];        if(!same(e.u,e.v))        {            unite(e.u,e.v);            res+=e.cost;        }    }    return res;}double dis(node a,node b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}void add(int u,int v,double c,int i){    es[i].u=u,es[i].v=v,es[i].cost=c;}int main(){    while(~scanf("%d",&V))    {        for(int i=0;i<V;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        E=0;        for(int i=0;i<V;i++)            for(int j=i+1;j<V;j++)                add(i,j,dis(p[i],p[j]),E++);        printf("%.2lf\n",kruskal());    }    return 0;} 
0 0