#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
const int INF=1e15;
typedef struct{
int to;
int val;
}Point;
int n,m,c;
vector<Point> map[120];
int dis[120];
int path[120];
void SPFA()
{
for(int i=2;i<=n;i++)
dis[i]=INF;
dis[1]=0;
queue<int>q;
q.push(1);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<map[u].size();i++)
{
Point v=map[u][i];
if(dis[v.to]>dis[u]+v.val)
{
dis[v.to]=dis[u]+v.val;
path[v.to]=u; //存每个点的前一个点
q.push(v.to);
}
}
}
}
int main()
{
//n为顶点数,m为边数,c为终点
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
memset(path,0,sizeof(path));
for(int i=0;i<=n;i++)
map[i].clear();
for(int i=1;i<=m;i++)
{
//u到v有一条有向边,权值为e
int u,v,e;
scanf("%d%d%d",&u,&v,&e);
Point s;
s.to=v;
s.val=e;
map[u].push_back(s);
}
SPFA();
int num[120];
int cnt=0;
printf("%d\n",dis[c]); //最短路径长
printf("1->"); //起始都是从1开始出发
for(int i=c;i!=1;i=path[i])
{
num[cnt++]=i;
}
for(int i=cnt-1;i>0;i--)
{
printf("%d->",num[i]);
}
printf("%d\n",num[0]);
}
return 0;
}
保存1->c的最短路径:用path[ ]记录在每个点最后一次松弛操作中,其前面那个点即可(保证了是最短路径)。