题意:最小生成树的问题,只不过这道题是有已经连好的m组点,将他们置0
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 800;
const int INF = 0x3f3f3f3f;
int n,m,u,v;
double x[MAXN],y[MAXN],dis[MAXN],map[MAXN][MAXN];
int vis[MAXN];
double dist(int i,int j){
return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
double Prim(){
int p;
double sum=0.0,Min;
memset(vis,0,sizeof(vis));
for (int i = 2; i <= n; i++)
dis[i] = map[1][i];
for (int i = 2; i <= n; i++){
Min = INF;
for (int j = 2; j <= n; j++)
if (!vis[j] && Min > dis[j]){
p = j;
Min = dis[j];
}
if (Min == INF)
return -1;
vis[p] = 1;
sum += Min;
for (int j = 2; j <= n; j++)
if (!vis[j] && dis[j] > map[p][j])
dis[j] = map[p][j];
}
return sum;
}
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 < i; j++)
map[i][j] = map[j][i] = dist(i,j);
scanf("%d",&m);
while (m--){
scanf("%d%d",&u,&v);
map[u][v] = map[v][u] = 0;
}
printf("%.2lf\n",Prim());
}
return 0;
}