问题 D: 最短路径

简介: 问题 D: 最短路径

问题 D: 最短路径

[命题人 : 外部导入]

时间限制 : 1.000 sec 内存限制 : 32 MB


题目描述

有n个城市m条道路(n<1000, m<10000),每条道路有个长度,请找到从起点s到终点t的最短距离和经过的城市名。


输入

输入包含多组测试数据。


每组第一行输入四个数,分别为n,m,s,t。


接下来m行,每行三个数,分别为两个城市名和距离。


输出

每组输出占两行。


第一行输出起点到终点的最短距离。


第二行输出最短路径上经过的城市名,如果有多条最短路径,输出字典序最小的那条。若不存在从起点到终点的路径,则输出“can’t arrive”。


样例输入 Copy

3 3 1 3

1 3 3

1 2 1

2 3 1

样例输出 Copy

2

1 2 3


分析:

该题是涉及多条最短路径的最短路径问题,由于要输出最短路径,pre定义成vector<int>型数组,在采用dfs遍历最短路径时考虑字典序问题,典型的Dijkstra+Dfs应用。

值得注意一点,据说这题可能会输入重复的边,所以用邻接表在codeup上只能拿50分,建议直接用邻接矩阵。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxv=1001;
const int inf=10000000;
struct node{
  int v,weight;
};
vector<node>Adj[maxv] ;
bool vis[maxv];
int dis[maxv];
vector<int>pre[maxv];//记录路径 
//dijkstra算法
void dijkstra (int n,int s) {
  fill(vis,vis+n+1,false);
  fill(dis,dis+n+1,inf); //初始化dis和vis
  dis[s] =0;//这里求零点到各点最短距离
  for(int i=0;i<n;i++) //循环n次
  {    
      int min=inf,u=-1;
    for(int j=1;j<=n;j++) 
     //找最短距离点 ,这里可以用优先队列存储dis下标更快 
    {
      if(!vis[j]&&dis[j]<min)
      {
        u=j;
        min=dis[j];
      }
    }
    if(u==-1) return ;//没有找到 
    vis[u] =true;//标记已经找到的u 
    for(int j=0;j<Adj[u].size();j++) //更新dis 
    {
      int x=Adj[u][j].v;
      if(!vis[x])
      {
        if(dis[u]+Adj[u][j].weight<dis[x]){
        dis[x]=dis[u]+Adj[u][j].weight;
        pre[x].clear();
        pre[x].push_back(u);}
        else if(dis[u]+Adj[u][j].weight==dis[x])
        pre[x].push_back(u);
      }
  } 
} 
}
vector<int>path,temppath; 
void dfs(int s,int t){
  if(t==s){
    temppath.push_back(t);
    int k=1,a=path.size(),b=temppath.size();
    if(a){
      while(a>0&&b>0){
        if(temppath[b--]>path[a--]){
          k=0;break;
  }
  if(temppath[b]<path[a])break;
}
    }
    if(k)path=temppath;
    temppath.pop_back();
    return;
  }
    temppath.push_back(t);
  for(int i=0;i<pre[t].size();i++)
  {
    dfs(s,pre[t][i]);
  }
  temppath.pop_back();
}
int main(){
  int n,m,s,t;
  int x,y,w;
  node temp;
  scanf("%d%d%d%d",&n,&m,&s,&t);
  for(int i=0;i<m;i++){
    scanf("%d%d%d",&x,&y,&w); 
    temp.weight=w;
    temp.v=x;
    Adj[y].push_back(temp);
    temp.v=y;
    Adj[x].push_back(temp);
  }
  dijkstra(n,s);
  if(dis[t]==inf)printf("can't arrive\n");
  else {
    dfs(s,t);
    printf("%d\n",dis[t]);
  for(int i=path.size()-1;i>=0;--i)printf("%d ",path[i]);}
  return 0;
}
相关文章
|
算法 C++
Dijkstra算法及其C++实现
如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小。
76 0
|
5月前
|
算法
第6章 最短路径
第6章 最短路径
|
6月前
|
算法
关于Dijkstra算法
关于Dijkstra算法
|
机器学习/深度学习 人工智能 算法
弗洛伊德算法(求最短路径)
用弗洛伊德算法求最短路径
1342:【例4-1】最短路径问题
1342:【例4-1】最短路径问题
|
存储 算法
秒懂算法 | BFS与最短路径
搜索包括BFS和DFS,这两种算法是算法竞赛的基础。本篇介绍BFS的扩展应用。
560 0
秒懂算法 | BFS与最短路径
|
算法
最短路径——Floyd算法
最短路径——Floyd算法
141 0
|
存储
问题 E: 最短路径问题
问题 E: 最短路径问题
|
算法
最短路径之Dijkstra算法
最短路径之Dijkstra算法
114 0
|
算法 C语言
最短路径——Dijkstra算法与Floyd算法
最短路径——Dijkstra算法与Floyd算法
208 0
最短路径——Dijkstra算法与Floyd算法