/*
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1203
题意:给定了城市的坐标,将城市所在的区域当做一个平面,
求将所有的城市连接起来所需的隧道的最小长度。
分析:最小生成树 prim算法
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
struct Node{
double x, y, length;
}node[111];
bool flag[111];
const double maxn = 100000000+1;
int main(){
#ifndef ONLINE_JUDGE
freopen( "in", "r", stdin);
#endif
int n, nCase = 0;
while(cin >>n, n){
memset(flag, true, sizeof(flag));
if(nCase++)
printf("n");
printf("Case #%d:n", nCase);
for(int i=0; i<n; i++)
scanf("%lf %lf", &node[i].x, &node[i].y);
//将第0个点当做起点,求其他点到第0个点的距离
for(int i=1; i<n; i++)
node[i].length = sqrt( (node[i].x-node[0].x)*(node[i].x-node[0].x) + (node[i].y-node[0].y)*(node[i].y-node[0].y) );
double sum = 0;
//将0放到U集合中
flag[0] = false;
int tag = 0;
for(int i=1; i<n; i++){
double Max = maxn;
for(int j=1; j<n; j++){
//flag[j]=true,表示j在V-U集合中,寻找最短边
if(flag[j] && node[j].length<Max){
tag = j;
Max = node[j].length;
}
}
sum += Max;
//将最短边在V-U中的点加入到U中
flag[tag] = false;
for(int j=1; j<n; j++){
//因为U中加入了新的点,将U到V-U中的边进行修改,node[j].length中保存的是从U到V-U中j点的最短边
if(flag[j]){
double len = sqrt( (node[j].x-node[tag].x)*(node[j].x-node[tag].x) + (node[j].y-node[tag].y)*(node[j].y-node[tag].y) ) ;
if(len < node[j].length)
node[j].length = len;
}
}
}
printf("The minimal distance is: %.2lfn", sum);
}
return 0;
}
Prim zoj 1203 Swordfish
最新推荐文章于 2024-07-13 13:36:16 发布