拉斯维加斯的奥特莱斯无法满足游客 (尤其是来自中国的游客) 的购物需求。因此,将在沙漠中建造一座新的奥特莱斯,其中将包含很多商店。所有的商店之间以道路连接。设计者希望道路的总长度能够最小化。奥特莱斯的投资人雇佣了一名数据挖掘专家,该专家告诉他,Nike 商店和 Apple 商店必须由道路直接相连。请帮助他找出在此条件下的道路最短总长度。商店可被视作点,道路就是连接两个商店之间的线段。
输入
有多组测试数据。
对于每组测试数据,第一行仅包含一个整数 N (3 <= N <= 50),表示商店的数目。商店的编号从 1 到 N 。第二行包含了两个整数 p, q,表示第 p 家商店是一家 Nike 商店,第 q 家商店是一家 Apple 商店。接下来的 N 行中,第 i 行描述了第 i 家商店的位置。商店的位置被表示为两个整数 x, y (-100 <= x, y <= 100),即商店的位置坐标是 (x, y)。这 N 家商店均位于不同的位置。
输入以 N=0 结束。
输出
每组测试数据,对应输出道路总长度的最小值。结果应舍入到小数点后 2 位数。
示例输入
4
2 3
0 0
1 0
0 -1
1 -1
0
示例输出
3.41
这道题目有些意思,输入是一个个点的坐标,我们需要将一个一个点之间距离算出来,装进邻接矩阵。(操作简单)。然后就是怎么处理NIKE 和apple 点是直接相连的,我们可以直接先将这两个点连起来(将距离数组填充),从这两个点开始寻找权值最小的点,就是先将这两个点加进集合中(数组标记),一般的套路就是从第一个点开始寻找权值最小的点,这个就是有点特殊,其他的操作就是跟模板一样.
代码:
#include<iostream>
#include<string.h>
#include<string>
#include<bits/stdc++.h>
using namespace std;
const int inf=(1<<21);
const int maxn=55;
double maap[maxn][maxn];
double d[maxn];
int vis[maxn];
typedef struct
{
double x;
double y;
}point;
point dian[maxn];
int main()
{
int i,j;
int n;
int p,q;
while(cin>>n)
{
memset(vis,0,sizeof(vis));
if(n==0)
break;
cin>>p>>q;
vis[p]=1;
vis[q]=1;
for(i=1;i<=n;i++)
{
cin>>dian[i].x>>dian[i].y;
}
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
{
if(i==j)
maap[i][j]=0;
else
{
double juli=sqrt((dian[i].x-dian[j].x)*(dian[i].x-dian[j].x)+(dian[i].y-dian[j].y)*(dian[i].y-dian[j].y));
maap[i][j]=juli;
maap[j][i]=juli;
}
}
for(i=1;i<=n;i++)
d[i]=maap[p][i];
for(i=1;i<=n;i++)
d[i]=min(d[i],maap[q][i]);
double res=0;
res+=maap[p][q];
int pos;
for(i=1;i<n;i++)
{
double minv=inf*1.0;
for(j=1;j<=n;j++)
if(!vis[j]&&minv>d[j])
{
pos=j;
minv=d[j];
}
if(minv!=inf*1.0)
{
res+=minv;
vis[pos]=1;
for(j=1;j<=n;j++)
{
if(!vis[j]&&d[j]>maap[pos][j])
d[j]=maap[pos][j];
}
}
}
printf("%.2lf\n",res);
}
return 0;
}