简单题,直接上kruskal,可惜花了700+ms。 #include "math.h" #include "float.h" #include <algorithm> #include <iostream> using namespace std; double pos[1000][2],ans; int N,M; struct node { int s,t; double dist; }nodes[1000005]; bool operator<(node& a,node& b) { return a.dist<b.dist; } double dist(int i,int j) { if(i==j) return DBL_MAX; return sqrt((pos[i][0]-pos[j][0])*(pos[i][0]-pos[j][0])+(pos[i][1]-pos[j][1])*(pos[i][1]-pos[j][1])); } int parent[1005]; int Find(int a) { if(parent[a]>=0) return parent[a]=Find(parent[a]); else return a; } void Union(int a,int b) { int minNode,maxNode; if(parent[a]>parent[b]) minNode=a,maxNode=b; else minNode=b,maxNode=a; parent[maxNode]+=parent[minNode]; parent[minNode]=maxNode; } int main() { int s,t; scanf("%d%d",&N,&M); for(int i=0;i<N;i++) { scanf("%lf%lf",&pos[i][0],&pos[i][1]); } for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { nodes[i*N+j].s=i; nodes[i*N+j].t=j; nodes[i*N+j].dist=dist(i,j); } } for(int i=0;i<M;i++) { scanf("%d%d",&s,&t); s--; t--; nodes[s*N+t].dist=nodes[t*N+s].dist=0; } sort(nodes,nodes+N*N); memset(parent,-1,sizeof(parent)); int edge=0; ans=0; for(int i=0;;i++) { int a=Find(nodes[i].s),b=Find(nodes[i].t); if(a==b) continue; Union(a,b); edge++; ans+=nodes[i].dist; if(edge==N-1) break; } printf("%.2lf/n",ans); return 0; }