题目描述
有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
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 1000;
const int inf = 1000000000;
int n, m, s, t; //n个城市,m条道路,起点s,重点t
struct node
{
int v;
int dis;
node(int _x, int _y)
{
v = _x;
dis = _y;
}
};
vector<node> adj[maxn];
vector<int> pre[maxn];
vector<int> temp, ans;
bool vis[maxn] = {false};
int d[maxn];
void dij(int s)
{
fill(d, d+maxn, inf);
d[s] = 0;
for(int i = 0; i < n; i++)
{
int u = -1, min = inf;
for(int j = 0; j < n; j++)
{
if(vis[j] == false && d[j] < min)
{
u = j;
min = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int j = 0; j < adj[u].size(); j++)
{
int v = adj[u][j].v;
if(vis[v] == false)
{
if(d[u] + adj[u][j].dis < d[v])
{
d[v] = d[u] + adj[u][j].dis;
pre[v].clear();
pre[v].push_back(u);
}else if(d[u] + adj[u][j].dis == d[v])
{
pre[v].push_back(u);
}
}
}
}
}
void dfs(int v)
{
if(v == s)
{
temp.push_back(v);
for(int i = temp.size() - 1; i >= 0; i--)
{
if(ans.size() == 0)
{
ans = temp;
}else
{
if(temp[i] == ans[i]) continue;
else if(temp[i] < ans[i])
{
ans = temp;
break;
}else if(temp[i] > ans[i]) break;
}
}
temp.pop_back();
return;
}
temp.push_back(v);
for(int i = 0; i < pre[v].size(); i++)
{
dfs(pre[v][i]);
}
temp.pop_back();
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for(int i = 0; i < m; i++)
{
int a, b, d;
scanf("%d%d%d", &a, &b, &d);
adj[a].push_back(node(b,d));
adj[b].push_back(node(a,d));
}
dij(s);
if(d[t] == inf) printf("can't arrive");
else
{
printf("%d\n", d[t]);
dfs(t);
for(int i = ans.size() - 1; i >= 0; i--)
{
printf("%d ", ans[i]);
}
}
return 0;
}
每次做一遍出来,都是答案错误50%....
排查半天,还是错误50%....
未完待解.....(算法虐我千百遍,我待算法如初恋)