题意:一个人可以步行10km/h也可以坐地铁40km/h。现在给出他的坐标和目的地的坐标。途中可以步行和地铁一起结合。然后给出每一条线的地铁入口坐标。
此题建图是重点:首先因为地铁是按照线路的,所以只能每个地铁相联系,这里用到了cnt1,小小技巧,然后对地铁建图。其次是每个点都有距离,则按照步行来建图,取最小。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 310;
struct Node
{
public:
double x,y;
}point[maxn];
const double inf = 1e30;
bool visit[maxn];
double gragh[maxn][maxn];
double dis[maxn];
int n;
double Distance(Node a,Node b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx+dy*dy);
}
void Dijkstra()
{
for(int i = 1;i <= n; i++)
dis[i] = gragh[1][i];
memset(visit,0,sizeof(visit));
visit[1] =true;
for(int i = 1;i <= n; i++){
double Min = inf;
int pos;
for(int j = 1;j <= n; j++){
if(visit[j] == 0 && dis[j] < Min){
Min = dis[j];
pos = j;
}
}
visit[pos] = true;
for(int j = 1;j <= n; j++){
if(visit[j] == 0 && dis[j] > dis[pos] + gragh[pos][j]){
dis[j] = dis[pos] + gragh[pos][j];
}
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
double v1 = 10000.0/60;
double v2 = 40000.0/60;
while(scanf("%lf%lf%lf%lf",&point[1].x,&point[1].y,&point[2].x,&point[2].y) != EOF){
for(int i = 1;i <= 300; i++){
for(int j = 1;j <= 300; j++){
if(i == j)
gragh[i][j] = 0;
else
gragh[i][j] = inf;
}
}
double dx,dy;
n = 2;
int cnt1 = 3;
while(scanf("%lf%lf",&dx,&dy) != EOF){
if(dx == -1 && dy == -1){
cnt1 = n + 1;
continue;
}
n++;
point[n].x = dx;
point[n].y = dy;
if(cnt1 != n){
gragh[n][n-1] = gragh[n-1][n] = min(gragh[n][n-1],Distance(point[n],point[n-1])/v2);
}
}
for(int i = 1;i <= n; i++){
for(int j = 1;j <= n; j++){
gragh[i][j] = gragh[j][i] = min(gragh[i][j],Distance(point[i],point[j])/v1);
}
}
Dijkstra();
printf("%.0f\n",dis[2]);
}
return 0;
}