http://poj.org/problem?id=2560
本题跟其他题差不多,只不过节点的权重需要自己计算
Freckles
| Time Limit:1000MS | Memory Limit:65536K |
Description
In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to form a picture of the Liberty Bell. Alas, one of the freckles turns out to be a scar, so his Ripley's engagement falls through.
Consider Dick's back to be a plane with freckles at various (x,y) locations. Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used. Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines. When Richie is done there must be a sequence of connected lines from any freckle to any other freckle.
Consider Dick's back to be a plane with freckles at various (x,y) locations. Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used. Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines. When Richie is done there must be a sequence of connected lines from any freckle to any other freckle.
Input
The first line contains 0 < n <= 100, the number of freckles on Dick's back. For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle.
Output
Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles.
Sample Input
3 1.0 1.0 2.0 2.0 2.0 4.0
Sample Output
3.41
/* Author : yan
* Question : POJ 2560 Freckles
* Date && Time : Monday, January 24 2011 07:43 PM
* Compiler : gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
*/
#include<stdio.h>
#define MAX 101
typedef struct _node
{
float x,y;
};
struct _node point[MAX];
typedef struct _edge
{
int x,y;
float weight;
};
struct _edge edge[MAX*MAX];
int father[MAX];
int rank[MAX];
float ans;
void initial()
{
int _i;
memset(rank,0,sizeof(rank));
for(_i=0;_i<MAX;_i++)
father[_i]=_i;
}
int Find_Set(int x)
{
if(x!=father[x])
{
father[x]=Find_Set(father[x]);
}
return father[x];
}
int Union(int x,int y,float w)
{
x=Find_Set(x);
y=Find_Set(y);
if(x==y) return 0;
else if(rank[x]<=rank[y])
{
father[x]=y;
rank[y]+=rank[x];
}
else
{
father[y]=x;
rank[x]+=rank[y];
}
ans+=w;
return 1;
}
int cmp( const void *a ,const void *b )
{
return (*(struct _edge *)a).weight > (*(struct _edge *)b).weight ? 1 : -1;
}
float dis(struct _node a,struct _node b)
{
float tmp=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt(tmp);
}
void print(int cnt)
{
int i;
for(i=0;i<cnt;i++)
printf("%d %d %g/n",edge[i].x,edge[i].y,edge[i].weight);
}
int main()
{
//freopen("input","r",stdin);
int n;
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%f %f",&point[i].x,&point[i].y);
}
int edge_cnt=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
edge[edge_cnt].x=i,edge[edge_cnt].y=j;
edge[edge_cnt].weight=dis(point[i],point[j]);
edge_cnt++;
}
}
//print(edge_cnt);
qsort(edge,edge_cnt,sizeof(edge[0]),cmp);
//print(edge_cnt);
initial();
for(i=0;i<edge_cnt;i++)
{
Union(edge[i].x,edge[i].y,edge[i].weight);
}
printf("%.2f",ans);
return 0;
}
本文介绍了一道经典的最小生成树问题——Freckles。题目要求通过连接平面上的若干个点(freckles),形成一个连通的图形,并使得所用的连线总长度最短。文章提供了一个使用 C 语言实现的解决方案,该方案首先计算了所有点之间的距离,然后利用 Kruskal 算法来找出最小生成树。
5万+

被折叠的 条评论
为什么被折叠?



