hdu 1875 畅通工程再续(最小生成树)

hdu 1875 畅通工程再续

http://acm.hdu.edu.cn/showproblem.php?pid=1875

Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
 

Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
 

Output
每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
 

Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
 

Sample Output
1414.2 oh!

 最小生成树问题,下面用 kruskal算法解答 

ac代码:#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define INF 99999
struct
{
 double x,y;
}dd[110];
int parent[110];
struct nod
{
 int x,y;
 double dv;
}node[5010];
int findp(int a)
{
 while(a!=parent[a])
  a=parent[a];
 return a;
}
double deal(nod a)
{
 int x=findp(a.x);
 int y=findp(a.y);
 if(x!=y)
 {
  parent[y]=x;
  return a.dv;
 }
 return 0;
}
double distance(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
int comp(nod a,nod b){return a.dv<b.dv;}
int main()
{
 int t;
 scanf("%d",&t);
 while(t--)
 {
  int i,j,n;
  scanf("%d",&n);
  for(i=1;i<=n;i++)
  {
   scanf("%lf%lf",&dd[i].x,&dd[i].y);
   parent[i]=i;
  }
  int k=0;
  for(i=1;i<=n;i++)
   for(j=i+1;j<=n;j++)
   {
    node[k].x=i;
    node[k].y=j;
    node[k].dv=distance(dd[i].x,dd[i].y,dd[j].x,dd[j].y);
    if(node[k].dv<10||node[k].dv>1000)
     node[k].dv=INF+1;
    k++;
   }
  int m=k;
  sort(node,node+m,comp);
  double sum=0,stemp;
  for(i=0;i<m;i++)
  {
   stemp=deal(node[i]);
   if(stemp>INF)
    break;
   else
    sum+=stemp;
  }
  if(i<m)
   printf("oh!\n");
  else
   printf("%.1lf\n",100*sum);
 }
 return 0;
}

原文地址:https://www.cnblogs.com/crazyapple/p/2999491.html