暑期集训
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,多数题都能过
附上题目链接点击打开链接
和代码链接点击打开链接