4 2 3 0 0 1 0 0 -1 1 -1 0
3.41
数据范围小。水的不能再水,没什么可说的,就是次小生成树
#include <stdio.h>
#include <string.h>
#include <cmath>
#define MAX 60
const double INF = 1000000000.0 ;
struct Point{
int x,y;
}p[MAX];
double graph[MAX][MAX] ,max[MAX][MAX] ;
bool used[MAX][MAX] , visited[MAX];
double prim(int n)
{
int closest[MAX];
double lowCost[MAX] , sum = 0.0;
memset(visited,false,sizeof(visited)) ;
memset(max,0,sizeof(max)) ;
memset(used,false,sizeof(used)) ;
for(int i = 1 ; i <= n ; ++i)
{
lowCost[i] = graph[1][i] ;
closest[i] = 1 ;
}
visited[1] = true ;
for(int i = 0 ; i < n-1 ; ++i)
{
double min = INF ;
int index = -1 ;
for(int j = 1 ; j <= n ; ++j)
{
if(!visited[j] && lowCost[j]<min)
{
min = lowCost[j];
index = j ;
}
}
if(index == -1)
{
break ;
}
sum += lowCost[index] ;
visited[index] = true ;
used[index][closest[index]] = used[closest[index]][index] = true ;
for(int j = 1 ; j <= n ; ++j)
{
if(visited[j] && j != index)
{
max[j][index] = max[index][j] = lowCost[index]>max[j][closest[index]]?lowCost[index]:max[j][closest[index]] ;
}
if(!visited[j] && lowCost[j]>graph[index][j])
{
lowCost[j] = graph[index][j] ;
closest[j] = index ;
}
}
}
return sum ;
}
double dis(const Point &p1 , const Point &p2)
{
int x = p1.x-p2.x , y = p1.y-p2.y ;
return sqrt((x*x+y*y)*1.0) ;
}
int main()
{
int n ;
while(~scanf("%d",&n) && n)
{
Point p[MAX] ;
int pt,qt;
scanf("%d%d",&pt,&qt);
for(int i = 1 ; i <= n ; ++i)
{
scanf("%d%d",&p[i].x,&p[i].y) ;
}
for(int i = 1 ; i <= n ; ++i)
{
graph[i][i] = 0 ;
for(int j = 1 ; j < i ; ++j)
{
graph[i][j] = graph[j][i] = dis(p[i],p[j]) ;
}
}
double sum = prim(n) ;
if(used[pt][qt])
{
printf("%.2lf\n",sum) ;
}
else
{
printf("%.2lf\n",sum+graph[pt][qt]-max[pt][qt]) ;
}
}
return 0 ;
}hdu 4463 Outlets Prim 次小生成树 简单题
原文地址:http://blog.csdn.net/lionel_d/article/details/43915839