dijkstra的(bfs队列实现)++ 路径还愿

暑期集训

 

1669: 躁动的小Z

时间限制: 1 Sec  内存限制: 128 MB
提交: 81  解决: 19
[提交][状态][讨论版]

题目描述

你猜怎么样?小Z追到Gakki了!Gakki邀请小Z去她家共进晚餐,小Z喜出望外。小Z的家和Gakki的家隔着几个街区,所以他决定乘坐公交车前往

Gakki家赴约。小Z的家在公交站台的起始站(编号为1),而Gakki家正好在末站(编号为n)。城市中有许多公交站台,有些站台之间可以通过公交

线路互相到达。现在给你n个公交站台和m条不同的公交线路的时间花费,请你帮助小Z分析一下最短的可以从家里来到Gakki身边的路径?

输入

有多组测试样例。


第一行两个正整数n,m(2≤n≤10^5,0≤m≤10^5),代表站台数与公交线路数量。


接下来m行每行三个正整数a[i],b[i],w[i],代表从公交站a[i]到b[i]需要花费的时间为w[i]。(1≤a[i],b[i]≤n,1≤w[i]≤10^6)


注意:公交线路可能会产生环,并且两个站台之间可能有多条公交线路。

输出

单独一行,输出花费时间最小时小Z经过的公交站台编号,以空格隔开;如果小Z无法到达Gakki的家,则输出-1.

样例输入

5 6
1 2 2
2 5 5
2 3 4
1 4 1
4 3 3
3 5 1

样例输出

1 4 3 5

 

 
#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = (int)1e5+5;  
const int INF = 0x3f3f3f3f;  //一个很大的数 
typedef pair<int,int>P; //类似于二维数组有  first  和 second  两个参数 
struct edge
{
	int to,w;
	edge(int _to,int _w) //自定义函数 
	{						/*  可以直接传入一个结构体变量   例如 edge(4,5)  就创建了一个新的结构体 */ 
		to = _to;
		w = _w;
	}
};
vector<edge> G[maxn];//二维不定数组  横向固定  纵向不固定 

int dis[maxn]; // 记录起点到这个位置的最小权 
int per[maxn];//记录前驱结点 
void slove(int s)
{
	priority_queue<P,vector<P>,greater<P> >que;
	memset(dis,INF,sizeof(dis));
	memset(per,-1,sizeof(per));
	dis[s] = 0;
	que.push(P(0,s));
	while(!que.empty())
	{
		P p = que.top(); que.pop();
		int v = p.second;
		if(dis[v]<p.first) continue;
		for(int i = 0;i<G[v].size();i++)
		{
			edge &e = G[v][i];
			if(dis[e.to]>e.w+dis[v])
			{
				dis[e.to] = e.w+dis[v];
				per[e.to] = v;
				que.push(P(dis[e.to],e.to));
			}
		 } 
	} 
 } 
 vector<int>get_path(int t)//路径还原 
{
	vector<int>path;
	for(;t!=-1;t = per[t])
	{
		path.push_back(t);
	}
	reverse(path.begin(),path.end());
	return path;
 } 
 int main()
 {
 	int n,m;
 	while(cin>>n>>m)
 	{
 		int x,y,w;
 		for(int i = 0;i<m;i++)
	 	{
	 		scanf("%d%d%d",&x,&y,&w);//输入格式 
	 		 G[x].push_back(edge(y,w));
	 		 G[y].push_back(edge(x,w));
		} 
		slove(1);
		if(dis[n]==INF) cout<<"-1"<<endl;
		else
		{
			vector<int>path;
			path = get_path(n);
			for(int i = 0;i<path.size();i++)
			{
				cout<<path[i]<<" ";
			}
			cout<<endl;
		}
		for(int i = 0;i<maxn;i++)
		{
			G[i].clear();
		}
	}
 	return 0;
 }

ps:该算法的时间复杂度为n*lgn,多数题都能过

附上题目链接点击打开链接

和代码链接点击打开链接

posted @ 2018-03-15 12:49  Nlifea  阅读(128)  评论(0编辑  收藏  举报