题意:要你求连通所有建筑物的最小距离,但是某些建筑物已经连通。
思路:最小生成树。已经连通的建筑物可以处理一下。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#define MAXN 755
using namespace std;
struct Edge
{
int a,b;
double weight;
};
bool vis[1005][1005];
Edge p[MAXN*MAXN];
int father[MAXN];
bool cmp(Edge x,Edge y)
{
return x.weight<y.weight;
}
int find(int p)
{
return p==father[p]?p:(father[p]=find(father[p]));
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int x[MAXN],y[MAXN];
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; ++i)
scanf("%d%d",&x[i],&y[i]);
int m;
scanf("%d",&m);
for(int i=0; i<m; ++i)
{
int u,v;
scanf("%d%d",&u,&v);
vis[u][v]=true;
}
int N=0;
for(int i=1; i<n; ++i)
for(int j=i+1; j<=n; ++j)
{
p[N].a=i;
p[N].b=j;
p[N++].weight=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
sort(p,p+N,cmp);
for(int i=0; i<=n; ++i)
father[i]=i;
double ans=0;
for(int i=0; i<N; ++i)
{
int ta=p[i].a,tb=p[i].b;
if(vis[ta][tb]||vis[tb][ta])
father[find(ta)]=find(father[tb]);
}
for(int i=0; i<N; ++i)
{
int ta=p[i].a,tb=p[i].b;
if(find(ta)!=find(tb))
{
ans+=p[i].weight;
father[find(ta)]=find(father[tb]);
}
}
printf("%.2lf\n",ans);
}
return 0;
}