码迷,mamicode.com
首页 > 编程语言 > 详细

hdu 1875 畅通工程再续(kruskal算法)

时间:2015-08-12 10:14:35      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

本题链接:点击打开链接

本题题意:

        有n个岛屿,给出每个岛屿的坐标,计算其距离当距离大于10或小于1000时舍去此边,每米距离建桥需花费100,求最少花费。

解题思路:

        本题先输入各桥坐标,然后使用两个for循环遍历出距每个岛距离最近的岛,将距离及i,j值存到一个结构体中,i,j就作为标号,然后就可使用kruskal算法来继续做了。

参考代码:

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
int per[110];
struct island{
	double x,y;
}a[110];
struct node{
	int u,v;
	double w;
}b[10010];
int cmp(node a,node b)
{
	return a.w<b.w;
}
double distance(double x1,double y1,double x2,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int find(int x)
{
	int r=x;
	while(r!=per[r])
		r=per[r];
	int j,i=x;
	while(i!=r)
	{
		j=per[i];
		per[i]=r;
		i=j;
	}
	return r;
}
void join(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	{
		per[fx]=fy;
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int flag=0;
		int c,k=0;
		scanf("%d",&c);
		for(int i=1;i<=c;i++)
		{
			per[i]=i;
			scanf("%lf%lf",&a[i].x,&a[i].y);
		}
		for(int i=1;i<c;i++)
		{
			for(int j=i+1;j<=c;j++)
			{
				double dis=distance(a[i].x,a[i].y,a[j].x,a[j].y);
				if(dis>=10&&dis<=1000)
				{
					b[k].w=dis;
					b[k].u=i;
					b[k++].v=j;
				}
			}
		}
		if(k<c-1)
		{
			printf("oh!\n");
			continue;
		}
		sort(b,b+k,cmp);
		double sum=0;
		for(int i=0;i<k;i++)
		{
			if(find(b[i].u)!=find(b[i].v))
			{
				join(b[i].u,b[i].v);
				sum+=b[i].w;
			}
			
		}
		for(int i=1;i<=c;i++)
			if(per[i]==i)
				flag++;
		if(flag==1)
			printf("%.1lf\n",sum*100);
		else
			printf("oh!\n");
	}
	return 0;
}


 

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 1875 畅通工程再续(kruskal算法)

标签:

原文地址:http://blog.csdn.net/lsgbb/article/details/47439423

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!