问题1:高速公路
(highway.pas)
问题描述:
现在政府计划在某个区域内的的城市间架设高速公路,以使任意两个城市间能够直接或间接到达,怎样修路,费用最小。
输入文件: highway.in
第一行一个整数 n(n<=100)表示城市数目。第二行至第n+1行每行两个数xi,yi(0<=xi,yi<=100)表示第i个城市的坐标;
输出文件:highway.out
输出最小费用。(结果保留两位小数)
输入样例:
3
1 1
1 2
1 3
输出样例:
2.00
#include <cstdio>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define MAXN INT_MAX
#define fi "highway.in"
#define fo "highway.out"
namespace Solve
{
int N;
struct Rec
{
int X;
int Y;
}Point[500];
double Map[300][300];
double lowcost[300];
int closest[300];
void Init_file();
void Read_data();
double prim(int v0);
void solve();
double calc(Rec x, Rec y);
}
double Solve::calc(Rec x, Rec y)
{
return (sqrt((x.X - y.X) * (x.X - y.X)
+ (x.Y - y.Y)
* (x.Y - y.Y)))
;
}
void Solve::Init_file()
{
freopen(fi, "r", stdin);
freopen(fo, "w", stdout);
}
void Solve::Read_data()
{
scanf("%d", &N);
for(int i = 0; i < N; i++)
{
int x;
int y;
scanf("%d%d", &x, &y);
Point[i].X = x;
Point[i].Y = y;
}
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
{
Map[i][j] = calc(Point[i], Point[j]);
Map[j][i] = Map[i][j];
}
}
double Solve::prim(int v0)
{
double ans = 0;
int minone;
double mindis;
for(int i = 0; i < N;i++)
{
lowcost[i] = Map[v0][i];
closest[i] = v0;
}
for(int i = 0; i < N - 1; i++)
{
mindis = MAXN;
for(int j = 0; j < N; j++)
{
if (lowcost[j] && mindis > lowcost[j])
{
mindis = lowcost[j];
minone = j;
}
}
ans += lowcost[minone];
lowcost[minone] = 0;
for(int j = 0; j < N; j++)
{
if (Map[minone][j] < lowcost[j])
{
lowcost[j] = Map[minone][j];
closest[j] = minone;
}
}
}
return ans;
}
void Solve::solve()
{
Init_file();
Read_data();
printf("%.2lf", prim(0));
}
int main()
{
Solve::solve();
return 0;
}
这道题嘛= =裸MST(最小生成树) 其他的没什么可说了
恩。。。实数 保留两位小数要注意直接用矩阵就可以了