求最短路径以及记录路径输出 wzy的大冒险——出发咯QAQ

 wzy的大冒险——出发咯QAQ

单点时限: 2.0 sec

内存限制: 512 MB

wzy踏上了冒险的旅程。
现在他从地精手里买了一份地图,地图上有n个城镇。
他从第一个城镇出发,走向(没钱只能走)第n个城镇,现在,请你帮wzy找到一条最短的路径,并倒序(从n到1)输出一条最短路径。
举个栗子:如果有两条路径6 4 3 1和6 5 2 1,我们选择6 4 3 1这条。
地精小提示:路是单向的QAQ。

输入格式

第一行两个数n,m ,(1≤n≤103,1≤m≤103)

接下来m行,每行三个数x,y,z,表示点 x 与点 y 之间有一条权值为 z 的有向边 (1≤x,y,z≤103).

输出格式

第一行一个整数表示 1 到 n 的最短距离;
第二行倒序输出这条路径。

样例

input

5 7
1 2 69
1 3 87
1 4 79
2 5 94
2 3 10
3 5 79
4 5 43

output

122
5 4 1

关键是利用d【maxn】数组去保存路径 然后进行输出  以及一些存图操作

#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e3+10;
typedef long long ll;
int way[maxn][maxn];//记录从点a到点b的距离
int dis[maxn];//某线段的权值
int flag[maxn];//用来标记走过的点
int d[maxn];//用来标记走过的点 
int n,m;//n是定点个数,m有多少个边
int dijkstra()
{
	memset(dis,0,sizeof(dis));
	for(int i=1;i<=n;i++)
	{
		dis[i]=way[1][i];//从1到第i的顶的距离赋给dis
		if(way[1][i]!=INF)
		{
			d[i]=1;//记录i点事由1到达的 
		 } 
	}
	flag[1]=1;dis[1]=0;
	int x;
	for(int i=1;i<=n;i++)//循环n次每次找到一个最近的点,走过的点标记 
	{
		int ans=INF;
		for(int j=1;j<=n;j++)
		{
			if(ans>dis[j]&&!flag[j])
			{
				ans=dis[j];
				x=j;
			}
		}
		flag[x]=1;//已经找到给一个标记
		for(int i=1;i<=n;i++)
		{
			if(!flag[i])
			{
				if(dis[i]>dis[x]+way[x][i])
				{
					dis[i]=dis[x]+way[x][i];
					d[i]=x;//记录到i点事由x过来的 
				}
			}
		 } 
	}
 }
 int main()
 {
 	cin>>n>>m;
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=n;j++)
 		{
 			way[i][j]=INF;//把每条路先赋成最大 
		 }
	 }
	 for(int i=1;i<=m;i++)
	{
	 	int a,b,c;
	 	cin>>a>>b>>c;
	 	way[a][b]=c;
	}
	dijkstra();
	cout<<dis[n]<<endl;
	int t=n;
	cout<<n<<" ";
	int s=1;
	while(t!=1)
	{
		t=d[t];
		if(s)
		{
			cout<<t;//注意下输出
			s=0; 
		}
		else cout<<" "<<t; 
	 }
	 return 0;
  } 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值