题目链接:
https://vjudge.net/problem/ZOJ-1203
题目大意:
给定平面上N个城市的位置,计算连接这N个城市所需线路长度总和的最小值。
思路:
模板题
最小生成树,Prim求解。注意两个城市之间都有一条边相连。还有每两组输出之间空一行。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<sstream>
using namespace std;
typedef long long ll;
const int maxn = 2e2 + ;
const int INF = << ;
int dir[][] = {,,,,-,,,-};
int T, n, m;
double Map[maxn][maxn];//存图
double lowcost[maxn];
int mst[maxn];
void prim(int u)//最小生成树起点
{
double sum_mst = ;//最小生成树权值
for(int i = ; i <= n; i++)//初始化两个数组
{
lowcost[i] = Map[u][i];
mst[i] = u;
}
mst[u] = -;//设置成-1表示已经加入mst
for(int i = ; i <= n; i++)
{
double minn = 1.0 * INF;
int v = -;
//在lowcost数组中寻找未加入mst的最小值
for(int j = ; j <= n; j++)
{
if(mst[j] != - && lowcost[j] < minn)
{
v = j;
minn = lowcost[j];
}
}
if(v != -)//v=-1表示未找到最小的边,
{//v表示当前距离mst最短的点
//printf("%d %d %d\n", mst[v], v, lowcost[v]);//输出路径
mst[v] = -;
sum_mst += lowcost[v];
for(int j = ; j <= n; j++)//更新最短边
{
if(mst[j] != - && lowcost[j] > Map[v][j])
{
lowcost[j] = Map[v][j];
mst[j] = v;
}
}
}
}
//printf("weight of mst is %d\n", sum_mst);
printf("The minimal distance is: %.2f\n", sum_mst);
}
double x[], y[];
int cases;
int main()
{
while(cin >> n && n)
{
if(cases)cout<<endl;
for(int i = ; i <= n; i++)cin >> x[i] >> y[i];
for(int i = ; i <= n; i++)
{
for(int j = ; j <= n; j++)
{
Map[i][j] = sqrt((x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]));
}
}
printf("Case #%d:\n", ++cases);
prim();
}
return ;
}