一遍过,本题运用的kruskal的思想,通过并查集实现。
获得两个点以及两个点间的距离,然后从集合中找出距离的最小值。加入到图的集合中,当把所有边都遍历完后,由于这个题,图肯定是连通的。所以只要记录加进来的边的长度(也就是两点间的距离就行)。
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
int n;
const int maxn=101;
float res;
struct Point{
float x,y;
};
struct G{
int from;
int to;
float weight;
inline bool operator <(const G &g)const{
return weight<g.weight;
}
};
vector<G> graph;
vector<Point> vec;
int father[maxn];
int height[maxn];
void init(int n){
for(int i=0;i<=n;i++){
father[i]=i;
height[i]=0;
}graph.clear();
vec.clear();
res=0;
}
float getdis(Point x,Point y){
return pow((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y),0.5);
}
int find(int x){
if(x!=father[x]){
father[x]=find(father[x]);
}
return father[x];
}
void Union(int x,int y,float weight){
x=find(x);
y=find(y);
if(x!=y){
res+=weight;
if(height[x]>height[y]){
father[y]=x;
}else if(height[x]<height[y]){
father[x]=y;
}else{
father[x]=y;
height[y]++;
}
}
}
int main(){
while(cin>>n){
init(n);
Point p;
G g;
for(int i=0;i<n;i++){
cin>>p.x>>p.y;
vec.push_back(p);
}
for(int i=0;i<vec.size()-1;i++){
for(int j=i+1;j<vec.size();j++){
g.from=i;
g.to=j;
g.weight=getdis(vec[i],vec[j]);
graph.push_back(g);
}
}
sort(graph.begin(),graph.end());
for(int i=0;i<graph.size();i++){
Union(graph[i].from,graph[i].to,graph[i].weight);
}
printf("%.2f\n",res);
}
return 0;
} 


京公网安备 11010502036488号