HDU - 1875 畅通工程再续

时间:2021-10-15 14:58:48
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!

一代模板如下

AC代码:(仅供参考)

  #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm> using namespace std; #define N 110000 int father[N]; int sum; struct no
{
int x,y;
}di[N]; struct node
{
int s,e;
double l;
}dd[N]; int Find(int n)
{
while(n!=father[n])
n=father[n]; return n;
} void Fin(int x,int y)
{
int a,b; a=Find(x);
b=Find(y); if(a!=b)
{
father[b]=a;
sum++;
}
} bool cmp(node a, node b)
{
return a.l < b.l;
} int main()
{
int t; scanf("%d",&t); while(t--)
{
int c; scanf("%d",&c); for(int i=; i<=c; i++)
father[i]=i; for(int i=; i<c; i++)
scanf("%d%d",&di[i].x, &di[i].y); if(c==)
{
printf("0.0\n");
continue;
} int k=; for(int i=; i<c; i++)
for(int j=i+; j<c; j++)
{
double mi=sqrt((double)(di[i].x-di[j].x)*(di[i].x-di[j].x)+(double)(di[i].y-di[j].y)*(di[i].y-di[j].y)); if(mi >= && mi <= )
{
dd[k].s=i;
dd[k].e=j;
dd[k].l=mi;
k++;
}
} sort(dd,dd+k,cmp); sum=;
double sun=; for(int i=; i<k; i++)
if(Find(dd[i].s) != Find(dd[i].e))
{
Fin(dd[i].s,dd[i].e);
sun+=dd[i].l;
} if(sum < c)
printf("oh!\n");
else
printf("%.1lf\n",sun*); }
return ;
}

不甘心,自己再来一

  #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm> using namespace std; #define N 110000 int p[N], s; struct data
{
int x, y;
}v[N]; struct node
{
int a, b;
double l;
}d[N]; bool cmp(node a, node b)
{
return a.l < b.l;
} int Find(int x)
{
while(p[x] != x)
x = p[x]; return x;
} void Fin(int x, int y)
{
int a = Find(x);
int b = Find(y); if (a != b)
{
s++;
p[b] = a;
}
} int main()
{
int T;
scanf ("%d", &T); while (T--)
{
int n; scanf ("%d", &n); for (int i = ; i <= n; i++)
p[i] = i; for (int i = ; i < n; i++)
scanf ("%d %d", &v[i].x, &v[i].y); int k = ; for (int i = ; i < n; i++)
for (int j = i+; j < n; j++)
{
double mi =sqrt((double)(v[i].x - v[j].x)*(v[i].x - v[j].x) + (double)(v[i].y - v[j].y)*(v[i].y - v[j].y)); if (mi >= && mi <= )
{
d[k].a = i;
d[k].b = j;
d[k].l = mi;
k++;
}
} double num = ;
s = ;
sort(d, d+k, cmp); for (int i = ; i < k; i++)
if (Find(d[i].a) != Find(d[i].b))
{
num += d[i].l;
Fin(d[i].a, d[i].b);
} if (s < n-)
printf ("oh!\n");
else
printf ("%.1f\n", *num);
}
return ;
}