问题 D: 最短路径
时间限制: 1 Sec 内存限制: 32 MB
献花: 81 解决: 14
[献花][花圈][TK题库]
题目描述
有n个城市m条道路(n<1000, m<10000),每条道路有个长度,请找到从起点s到终点t的最短距离和经过的城市名。
输入
输入包含多组测试数据。
每组第一行输入四个数,分别为n,m,s,t。
接下来m行,每行三个数,分别为两个城市名和距离。
输出
每组输出占两行。
第一行输出起点到终点的最短距离。
第二行输出最短路径上经过的城市名,如果有多条最短路径,输出字典序最小的那条。若不存在从起点到终点的路径,则输出“can’t arrive”。
样例输入
3 3 1 3
1 3 3
1 2 1
2 3 1
样例输出
2
1 2 3
Dijkstra算法
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cfloat>
#include <map>
#define INF INT32_MAX
using namespace std;
struct node
{
int w;
int v;
node(int a, int b) :v(a), w(b) { };
};
const int MaxN = 1010;
int des[MaxN], pre[MaxN];
vector<node> G[MaxN];
bool visited[MaxN];
int N;
void Dijkstra(int s)
{
fill(des, des + N + 1, INF);
for (int i = 0; i < N; ++i)pre[i] = i;
memset(visited, 0,N + 1);
des[s] = 0;
for (int i = 1,Min,u; i <= N; ++i)
{
Min = INF, u = -1;
for (int k = 1; k <= N; ++k)
{
if (!visited[k] && Min > des[k])
{
Min = des[k];
u = k;
}
}
if (u == -1)return;
visited[u] = true;
for (int k = 0; k < G[u].size(); ++k)
{
int v = G[u][k].v;
if(!visited[v])
{
if (des[v] > des[u] + G[u][k].w)
{
des[v] = des[u] + G[u][k].w;
pre[v] = u;
}
else if (des[v] == des[u] + G[u][k].w && pre[v] > u)
{
pre[v] = u;
}
}
}
}
}
void DFS(int s, int e)
{
if (s == e)
{
cout << e << " ";
return;
}
DFS(s, pre[e]);
cout << e << " ";
}
int main()
{
#ifdef _DEBUG
freopen("data.txt", "r+", stdin);
#endif // _DEBUG
std::ios::sync_with_stdio(false);
int M,s,t;
while(cin >> N >> M >> s >> t)
{
for (int i = 1; i <= N; ++i)
G[i].clear();
for (int i = 0, d = 1; i < M; ++i, d *= 2)
{
int u, v, w;
cin >> u >> v >> w;
G[u].push_back(node(v, w));
G[v].push_back(node(u, w));
}
Dijkstra(s);
if (des[t] != INF)
{
cout << des[t] << endl;
DFS(s, t);
}
else
cout << "can't arrive";
cout << endl;
}
return 0;
}
/**************************************************************
Problem: 1987
User: Sharwen
Language: C++
Result: 升仙
Time:103 ms
Memory:2396 kb
****************************************************************/
SFPA算法
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cfloat>
#include <map>
#define INF INT32_MAX
using namespace std;
struct node
{
int w;
int v;
node(int a, int b) :v(a), w(b) { };
};
const int MaxN = 1010;
int des[MaxN], pre[MaxN];
vector<node> G[MaxN];
bool isInq[MaxN];
int N;
void Dijkstra(int s)
{
fill(des, des + N + 1, INF);
for (int i = 0; i < N; ++i)pre[i] = i;
memset(isInq, 0,N + 1);
des[s] = 0;
queue<int>que; que.push(s);
while (que.size())
{
int u = que.front(); que.pop(); isInq[u] = false;
for (auto i = 0; i < G[u].size(); ++i)
{
int v = G[u][i].v;
if (des[v] > des[u] + G[u][i].w)
{
des[v] = des[u] + G[u][i].w;
pre[v] = u;
que.push(v); isInq[v] = true;
}
else if (des[v] == des[u] + G[u][i].w && pre[v] > u)
pre[v] = u;
}
}
}
void DFS(int s, int e)
{
if (s == e)
{
cout << e << " ";
return;
}
DFS(s, pre[e]);
cout << e << " ";
}
int main()
{
#ifdef _DEBUG
freopen("data.txt", "r+", stdin);
#endif // _DEBUG
std::ios::sync_with_stdio(false);
int M,s,t;
while(cin >> N >> M >> s >> t)
{
for (int i = 1; i <= N; ++i)
G[i].clear();
for (int i = 0, d = 1; i < M; ++i, d *= 2)
{
int u, v, w;
cin >> u >> v >> w;
G[u].push_back(node(v, w));
G[v].push_back(node(u, w));
}
Dijkstra(s);
if (des[t] != INF)
{
cout << des[t] << endl;
DFS(s, t);
}
else
cout << "can't arrive";
cout << endl;
}
return 0;
}
/**************************************************************
Problem: 1987
User: Sharwen
Language: C++
Result: 升仙
Time:117 ms
Memory:2404 kb
****************************************************************/