想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:有N个农场,现在给出他们的坐标,并且已经知道了有些农场他们之间是已经相连的了,现在问怎么连最小的边,能将这些农场都连接起来
解题思路:变相的最小生成树,即将已经连起来的边的权值置为-1,那么根据prim算法,优先选的就是那条-1边,这样我们在选边的时候,如果是-1边我们就可以不用加进来
/*
Memory 8096K
Time 94MS
*/
#include <stdio.h>
#include <math.h>
#define MAXV 1005
#define inf 1e12
typedef struct{
double x,y;
}Point;
Point point[MAXV];
int n,m;
double map[MAXV][MAXV];
double distance(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void prim(){
int i,j,vis[MAXV],v;
double mi,d[MAXV];
for(i=1;i<=n;i++){
vis[i]=0;
d[i]=map[1][i];
}
for(i=1;i<=n;i++){
mi=inf;
for(j=1;j<=n;j++)
if(!vis[j] && d[j]<mi){
mi=d[j];
v=j;
}
vis[v]=1;
for(j=1;j<=n;j++)
if(!vis[j] && d[j]>map[v][j])
d[j]=map[v][j];
}
for(d[0]=0,i=1;i<=n;i++)
if(d[i]!=-1) d[0]+=d[i];
printf("%.2lf\n",d[0]);
}
int main(){
int i,j,a,b;
while(~scanf("%d%d",&n,&m)){
for(i=1;i<=n;i++) scanf("%lf%lf",&point[i].x,&point[i].y);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=map[j][i]=distance(point[i],point[j]);
for(i=1;i<=m;i++){
scanf("%d %d",&a,&b);
map[a][b]=map[b][a]=-1;
}
prim();
}
return 0;
}