思路:
将已有的道路加入到一个集合中,并将所有边加入到优先队列当中,最后在原有图的基础上找最小生成树。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct node{
ll x,y;
double t;
friend bool operator < (node a, node b)
{
return a.t > b.t;
}
};
priority_queue<node>q;
ll f[10100];
node now;
ll gx[10100];
ll gy[10100];
double g[10100][10100];
ll find(ll x)
{
return x == f[x] ?x:f[x]=find(f[x]);
}
int main()
{
ll n,m;
cin>>n>>m;
for(ll i = 1; i <= n; i++) f[i] = i;
for(ll i = 1; i <= n; i++)
{
ll x,y;
cin>>x>>y;
now.x = gx[i] = x;
now.y = gy[i] = y;
}
while(m--)
{
ll u,v;
cin>>u>>v;
f[find(u)] = find(v);
g[u][v] = g[v][u] = sqrt((double)pow(abs(gy[u]-gy[v]),2) + (double)pow(abs(gx[u]-gx[v]),2));
}
for(ll i = 1; i <= n; i++)
{
for(ll j = i+1; j <= n; j++)
{
now.x = i;
now.y = j;
now.t = sqrt((double)pow(abs(gy[j]-gy[i]),2) + (double)pow(abs(gx[i]-gx[j]),2));
q.push(now);
}
}
double ans = 0.0;
ll cnt = 0;
while(cnt < n-1)
{
if(q.empty())
break;
now = q.top();
q.pop();
if(find(now.x) != find(now.y))
{
cnt++;
ans += now.t-g[now.x][now.y];
f[find(now.x)] = f[find(now.y)];
}
}
printf("%0.2lf\n",ans);
}