• 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,多数题都能过

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

    和代码链接点击打开链接

  • 相关阅读:
    成功在C#和VB中将shp转换为CAD
    java 提取字符串中的数字
    java 通用文件下载 excel,pdf,word,jpg,exe,rar
    java org 写excel
    java 通用文件下载 excel,pdf,word,jpg
    重建MDB空间网格大小的工具
    redis5.0 Cluster集群搭建
    选中对象【WPF】自定义控件之依赖属性
    成员函数对象类的const和非const成员函数的重载
    设备注册Linux加载DTS设备节点的过程(以高通8974平台为例)
  • 原文地址:https://www.cnblogs.com/Nlifea/p/11746075.html
Copyright © 2020-2023  润新知