这是典型的最小生成树的题目,把已有的边权值设为0即可
下面是代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 800;
const double inf = 10000000;
int n, m;
double x[N], y[N], map[N][N];
double prim( ) {
int u;
double ans = 0, ma;
bool vis[N];
memset( vis, 0, sizeof(vis) );
vis[1] = true;
for ( int k = 2; k <= n; ++k ) {
ma = inf;
for ( int i = 1; i <= n; ++i )
if ( !vis[i] && map[1][i] < ma ) ma = map[1][i], u = i;
ans += ma;
vis[u] = true;
for ( int i = 1; i <= n; ++i )
if ( !vis[i] && map[u][i] < map[1][i] ) map[1][i] = map[u][i];
}
return ans;
}
int main()
{
while ( scanf("%d", &n) != EOF ) {
for ( int i = 1; i <= n; ++i ) scanf("%lf%lf", &x[i], &y[i]);
for ( int i = 1; i <= n; ++i )
for ( int j = 1; j <= n; ++j ) {
if ( i != j ) map[i][j] = sqrt( (x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]) );
else map[i][j] = 99999999.0;
}
scanf("%d", &m);
for ( int i = 0; i < m; ++i ) {
int u, v;
scanf("%d%d", &u, &v);
map[u][v] = map[v][u] = 0;
}
printf("%.2lf\n", prim());
}
}