思路:
- 最小生成树,Prim。要注意即使是 double,闭区间也是必须写成闭区间的 ( >= )。
代码:
#include <iostream>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 105;
int N;
bool ok;
double ans;
double dis[maxn];
bool vis[maxn];
double mp[maxn][maxn];
struct ORD{
int x,y;
}ord[maxn];
struct NODE{
int id;
double dis;
friend bool operator > (NODE a, NODE b){
return a.dis > b.dis;
}
NODE(int id,double dis) : id(id) , dis(dis) {} ;
};
priority_queue<NODE , vector<NODE> , greater<NODE> >Q;
void INIT(){
ans = 0;
ok = true;
for(int i=0;i<maxn;i++){
dis[i] = 1500;
}
memset(vis,0,sizeof(vis));
return ;
}
void PRIM(){
Q.push(NODE(1,0)) ; dis[1]=0 ;
while(Q.size()){
NODE cur = Q.top() ; Q.pop() ;
int id = cur.id ;
if(vis[id])
continue;
vis[id] = true;
ans += dis[id];
for(int i=1;i<=N;i++)
if(!vis[i] && dis[i] > mp[id][i]){
dis[i] = mp[id][i];
Q.push(NODE(i , dis[i]));
}
}
for(int i=1;i<=N;i++)
if(!vis[i]){
ok = false;
break;
}
return ;
}
int main(){
int T;cin>>T;
while(T--){
INIT();
cin>>N;
for(int i=1;i<=N;i++)
cin>>ord[i].x>>ord[i].y;
for(int i=1;i<=N;i++){
for(int j=i+1;j<=N;j++){
double w = sqrt((ord[i].x - ord[j].x)*(ord[i].x - ord[j].x) + (ord[i].y - ord[j].y)*(ord[i].y - ord[j].y)) ;
if(w >= 10 && w <= 1000)
mp[i][j] = mp[j][i] = w;
else
mp[i][j] = mp[j][i] = 2000;
}
mp[i][i] = 0;
}
PRIM();
if(ok)
printf("%.1f\n" , 100*ans);
else
cout<<"oh!"<<endl;
}
return 0;
}