题目描述
Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he can travel from any farm to any other farm via a sequence of roads; roads already connect some of the farms.
Each of the N (1 ≤ N ≤ 1,000) farms (conveniently numbered 1..N) is represented by a position (Xi, Yi) on the plane (0 ≤ Xi ≤ 1,000,000; 0 ≤ Yi ≤ 1,000,000). Given the preexisting M roads (1 ≤ M ≤ 1,000) as pairs of connected farms, help Farmer John determine the smallest length of additional roads he must build to connect all his farms.
给出nn个点的坐标,其中一些点已经连通,现在要把所有点连通,求修路的最小长度.
输入输出格式
输入格式:
-
Line 1: Two space-separated integers: N and M
-
Lines 2..N+1: Two space-separated integers: Xi and Yi
- Lines N+2..N+M+2: Two space-separated integers: i and j, indicating that there is already a road connecting the farm i and farm j.
输出格式:
- Line 1: Smallest length of additional roads required to connect all farms, printed without rounding to two decimal places. Be sure to calculate distances as 64-bit floating point numbers.
输入输出样例
输入样例#1:
4 1
1 1
3 1
2 3
4 3
1 4
输出样例#1:
4.00
思路:裸的最小生成树。注意精度问题。
错因:数组开小了+本题存在精度问题。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 1000000 using namespace std; int n,m,num,tot,x[MAXN],y[MAXN],fa[MAXN],map[1010][1010]; double ans; struct nond{ int x,y; double z; }edge[MAXN]; int cmp(nond a,nond b){ return a.z<b.z; } int find(int x){ if(fa[x]==x) return fa[x]; else return fa[x]=find(fa[x]); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for(int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); map[u][v]=map[v][u]=1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(i==j) continue; edge[++tot].x=i; edge[tot].y=j; double w=sqrt(double(x[i]-x[j])*double(x[i]-x[j])+double(y[i]-y[j])*double(y[i]-y[j])); edge[tot].z=w; if(map[i][j]||map[j][i]) edge[tot].z=0; } for(int i=1;i<=n;i++) fa[i]=i; sort(edge+1,edge+1+tot,cmp); for(int i=1;i<=tot;i++){ int dx=find(edge[i].x); int dy=find(edge[i].y); if(dx==dy) continue; ans+=edge[i].z; num++; fa[dx]=dy; if(num==n-1) break; } printf("%.2lf",ans); }