Problem A Codeforces 20C 最短路(dj,spfa)

Description

You are given a weighted undirected graph. The vertices are enumerated from 1 to n. Your task is to find the shortest path between the vertex 1 and the vertex n.

Input

The first line contains two integers n and m (2 ≤ n ≤ 105, 0 ≤ m ≤ 105), where n is the number of vertices and m is the number of edges. Following m lines contain one edge each in form aibi and wi (1 ≤ ai, bi ≤ n, 1 ≤ wi ≤ 106), where ai, bi are edge endpoints and wi is the length of the edge.

It is possible that the graph has loops and multiple edges between pair of vertices.

Output

Write the only integer -1 in case of no path. Write the shortest path in opposite case. If there are many solutions, print any of them.

Sample Input

Input
5 6
1 2 2
2 5 5
2 3 4
1 4 1
4 3 3
3 5 1
Output
1 4 3 5 
Input
5 6
1 2 2
2 5 5
2 3 4
1 4 1
4 3 3
3 5 1
Output
1 4 3 5 

最短路
我用的DJ
之前没写出来的原因是不会保存路径
 1 #include<stdio.h>
 2 #include<queue>
 3 #define LL long long
 4 using namespace std;
 5 const int maxn = 400005;//这个给大一点,四倍
 6 const LL maxd = 1E13;
 7 int v[maxn],w[maxn],next[maxn],pre[maxn],res[maxn];
 8 int first[maxn],inq[maxn],e;
 9 LL d[maxn];
10 
11 void init()
12 {
13     for(int i=0;i<maxn;i++)
14     {
15         first[i]=-1;
16     }
17     e=0;
18 }
19 
20 
21 void addeage(int x,int y,int z)
22 {
23     v[e]=y;
24     w[e]=z;
25     next[e]=first[x];
26     first[x]=e;
27     e++;
28 }
29 
30 void spfa(int s)
31 {
32     queue<int> q;
33     for(int i =0;i<maxn;i++)
34         d[i]=maxd;
35     d[s]=0;inq[s]=1;q.push(s);
36     while(q.empty()==false)
37     {
38         int u = q.front();
39         q.pop();
40         inq[u]=0;
41         for(int i =first[u];i!=-1;i=next[i])
42         {
43             if(d[v[i]]>d[u]+w[i])
44             {
45                 d[v[i]]=(d[u]+w[i]);
46                 pre[v[i]]=u;//把前一个点存储
47                 if(inq[v[i]]==0)
48                 {
49                     q.push(v[i]);
50                     inq[v[i]]=1;
51                 }
52             }
53         }
54     }
55 }
56 
57 int main()
58 {
59     init();
60     int m,n;
61     scanf("%d%d",&m,&n);
62     int x,y,z;
63     while(n--)
64     {
65         scanf("%d%d%d",&x,&y,&z);
66         addeage(x,y,z);
67         addeage(y,x,z);//Undirected无向图,双向的
68     }
69     spfa(1);
70     if(d[m]==maxd)
71         printf("-1");
72     else
73     {
74         int now=m;//从终点开始把之前的一个个找出来
75         int cnt=0;
76         while(now!=1)
77         {
78            res[cnt++] = now;//用来保存路径
79            now = pre[now];
80         }
81         res[cnt++] = 1;
82         for(int i = cnt-1;i >= 0;i--)
83             printf("%d ",res[i]);
84     }
85     return 0;
86 }
87     

 



转载于:https://www.cnblogs.com/Run-dream/p/3889316.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值