一道最小生成树的基本题吧,这里要注意两点
1.数组范围要开大,毕竟是生成树,开n平方即可
2.求边上权值算两点之间距离要注意精度的问题,多强制转换几次(double)防止WA
就OK了,剩下是Kruskal模板
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; int n,m,cnt; double ans; int x[1000005],y[1000005],fa[1000005]; struct Node{ int x; int y; double dis; }a[1000005]; inline int Find(int i){ if(fa[i]==i)return i; return fa[i]=Find(fa[i]); } inline void Union(int x,int y){ int f1=Find(x); int f2=Find(y); if(f1!=f2)fa[f1]=f2; return; } inline bool cmp(Node a,Node b){ if(a.dis==b.dis)return a.x<b.x; return a.dis<b.dis; } int main(){ scanf("%d%d",&n,&m); for(register int i=1;i<=n;i++) fa[i]=i; for(register int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for(register int i=1;i<=n;i++) for(register int j=i+1;j<=n;j++){ a[++cnt].x=i; a[cnt].y=j; a[cnt].dis=(double)sqrt((double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j])); } int x,y; for(register int i=1;i<=m;i++){ scanf("%d%d",&x,&y); a[++cnt].x=x; a[cnt].y=y; a[cnt].dis=0.0; } sort(a+1,a+cnt+1,cmp); for(register int i=1;i<=cnt;i++){ if(Find(a[i].x)!=Find(a[i].y)){ Union(a[i].x,a[i].y); ans+=a[i].dis; } } printf("%.2lf\n",ans); return 0; }