/*
思路:用克鲁斯卡尔求最小生成树,并且限制路的长度即可
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<math.h>
#include<algorithm>
using namespace std;
struct edge
{
int from,to;
double w;
};
struct di
{
int x,y;
};
int pre[101];
di a[101];
vector<edge>edges;
int n,m;
bool comp( edge a, edge b){
return a.w < b.w; //<升序,>降序
}
void addedge(int x,int y,double w)
{
edge v={x,y,w};
edges.push_back(v);
}
int find(int x)
{
if(x==pre[x])
{
return x;
}
else
{
pre[x]=find(pre[x]);
return pre[x];
}
}
void kluska()
{
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
double sum;
int top=n;
for(int i=0;i<edges.size();i++)
{
edge v=edges[i];
if(v.w<10||v.w>1000) continue;//限制路的长度
int f1=find(v.from);
int f2=find(v.to);
if(f1!=f2)
{
pre[f2]=f1;
top--;
sum+=v.w;
}
}
if(top==1) printf("%.1lf\n",sum*100);
else printf("oh!\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
edges.clear();
for(int i=1;i<=n;i++)
{
scanf("%d %d",&a[i].x,&a[i].y);
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
double sum=sqrt((a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y));
addedge(i,j,sum);
}
}
sort(edges.begin(),edges.end(),comp);
kluska();
}
}
hdu1875
最新推荐文章于 2020-02-07 11:05:28 发布