问题描述:
兔子很热爱学习,为了多学习她希望可以找最快的路线去上学。她的城市里有N个(2 <= N <= 1000)个地铁站,编号分别为1…N。兔子家在1号地铁站旁边,学校是N号地铁站。地铁站之间共有M (1 <= M <= 2000)条双向路径。兔子现在在1号地铁站,她希望知道到学校最短需要多少时间。可以保证兔子能到达学校。忽略换乘地铁的等待时间
Input
第一行:m和n
接下来的m行:每一行有x,y,z三个整数。代表x站到y站或者y站到x站需要z分钟(1<=z<=100)
Output
兔子到学校最少需要多少时间。
直接思路:
直接最短路径,有一个地方,题目没有说明白,就是从一个地方到另一个地方可能有用时不一样的,要取最小的。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stdio.h>
#include <queue>
using namespace std;
struct Node {
int num; //编号
int d; //从起点到该点的最短路程
bool operator < (const Node &a) const {
return d>a.d;//最小值优先
}
};
const int _inf = 0x3f3f3f3f;
const int N = 1010;
int m,n;
int map[N][N];
int dis[N];//如果要记录路线,还可以加一个pre[N]记录前驱
int vis[N];
void Dijkstra(int s)
{
for(int i = 1; i <= n; i++)
dis[i] = _inf;
// for(int i = 1; i <= n; i++) //本题不需要记录前驱
// pre[i] = -1;
dis[s] = 0;
priority_queue<Node> q;
Node temp = {s,dis[s]};
q.push(temp);
while(!q.empty())
{
int u = q.top().num;
q.pop();
if(vis[u])//如果被标记过,直接跳过
continue;
vis[u] = true;
for(int v = 1; v <= n; v++)
{
if(!vis[v]&&map[u][v]&&dis[u]+map[u][v] < dis[v])
{
dis[v] = dis[u] + map[u][v];
// pre[v] = u; //前驱
temp.num = v;
temp.d = dis[v];
q.push(temp);
}
}
}
}
int main()
{
int x,y,z;
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
for(int i = 0; i < m; i++)
{
scanf("%d%d%d",&x,&y,&z);
if(!map[x][y]) //这就那个小陷阱
{
map[x][y] = map[y][x] = z;
}
else
{
if(map[x][y] > z)
map[x][y] = map[y][x] = z;
}
}
Dijkstra(1);
printf("%d\n",dis[n]);
}
return 0;
}