#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>
using namespace std;
const int MAXN =205;//节点数目
const int INF = 0x3f3f3f3f;
int dis[MAXN];//源点到其他点的最短距离
int mp[MAXN][MAXN];//所有点之间的距离
int vis[MAXN];//访问节点标记
int pre[MAXN];//记录最短路径上某一节点的上一节点 ,用于输出路径
stack<int> path; //由于记录的中途节点是倒序的,所以使用栈(先进后出),获得正序
int main()
{
int n, m;//n个点,m条线
int i,j,a, b, c;
while(cin >> n >> m)
{
memset(mp, 0x3f, sizeof(mp));//初始化一个较大的值
for(i = 0;i < n;++i)//一定不要忘这个特殊的初始化
mp[i][i] = 0;
for(i = 0;i < m;++i)
{
cin >> a >> b >> c;//a到b路长c
mp[a][b] = min(mp[a][b], c);//若两点直连多条线,选短的
//mp[b][a] = mp[a][b];//决定单双向
}
cin >> a >> b;//输入起点终点a,b
memset(dis, 0x3f, sizeof(dis));//初始化一个较大的值
for(i = 0;i < n;++i)
dis[i] = mp[a][i];
memset(vis, 0, sizeof(vis));//初始化未访问
vis[a] = 1;
memset(pre, -1, sizeof(pre));//初始化
int v, mi;
//每次都 vis 一个点,加上上面一次 vis, 所以一共 vis n次
for(i = 1;i < n;++i)
{
//选出当前离 s 最近的点
mi = INF;
for(j = 0;j <n;++j)
{
if(!vis[j] && dis[j] < mi)
{
mi = dis[j];
v = j;
}
}
vis[v] = 1;
//更新 dis
for(j = 0;j < n;++j)
{
if(!vis[j] && mi + mp[v][j] < dis[j])
{
dis[j] = mi + mp[v][j];
pre[j]=v;//记录中途节点
}
}
}
if(dis[b]==INF)
{
cout<<"no way!\n";
printf("-1\n");
}
else
{
int temp=b;
while(pre[temp]!=-1) //如果temp有中途节点
{
path.push(temp); //将temp压入堆
temp=pre[temp]; //将temp的前个中途节点赋给temp
}
path.push(temp);
cout<<"path:"<<a;
while(!path.empty()) //先进后出,获得正序
{
printf(" %d",path.top());//打印堆的头节点
path.pop(); //将堆的头节点弹出
}
printf("\n");
cout<<"distance:";
printf("%d\n",dis[b]);
}
}
}
/*
6 8
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60
1 5
*/
输入
点数,边数
m点 n点 距离
...
a点 b点
输出
a->b 路径
a->b 距离