杭电1875.
做这个题的时候,我以为两个小岛间的距离小于10米就是相通的,就把这两个小岛放到一个集合里去。结果wrong answer。另外如果在使用并查集的是有不路径压缩就会超时。并且因为是double型数,所以涉及到精度问题。distance>=10.0 && distance <= 100.000001 ;
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
typedef struct
{
int a , b ;
double distance ;
}Edge ;
vector<Edge>edge ;
double xa[202] ;
double yb[202] ;
double shortcost = 0.0 ;
int root[202] ;
int t , c , x , y ;
int leng ;
bool com(Edge from , Edge to)
{
return from.distance < to.distance ;
}
double dist(double x1 , double x2 , double y1 , double y2 )
{
return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
}
void makeset(int i)
{
root[i] = i ;
}
int findfather(int i)
{
int k , j ;
j = i ;
while(root[i] != i)
{
i = root[i] ;
}
while(j != i)
{
k = root[j] ;
root[j] = i ;
j = k ;
}
return i ;
}
void unio(int i , int j )
{
root[i] = j ;
}
void kruskal()
{
sort(edge.begin() , edge.end() , com) ;
int s , t ;
shortcost = 0.0 ;
leng = c ;
for(int i = 0; i < (int)edge.size(); i ++)
{
s = findfather(edge[i].a) ;
t = findfather(edge[i].b) ;
if(s != t)
{
if(edge[i].distance >= 10.000000 && edge[i].distance <= 1000.000001)
{
unio(s , t);
shortcost += edge[i].distance * 100 ;
leng --;
}
}
}
}
int main()
{
scanf("%d", &t) ;
while(t--)
{
edge.clear();
scanf("%d",&c);
for(int i = 0; i < c; i ++)
{
scanf("%lf %lf",&xa[i], &yb[i]);
}
Edge temp ;
for(int i = 0; i <c; i ++)
for(int j = i+1 ; j < c; j ++)
{
temp.a = i ;
temp.b = j ;
temp.distance = dist(xa[i] , xa[j] , yb[i] , yb[j]) ;
edge.push_back(temp) ;
}
for(int i = 0; i < c; i ++)
makeset(i) ;
kruskal();
if(leng > 1)
cout << "oh!" << endl ;
else
printf("%.1lf\n", shortcost) ;
}
return 0 ;
}