CF20C Dijkstra?
题意翻译
题目大意
给出一张图,请输出其中任意一条可行的从点 111 到点 nnn 的最短路径。
输入输出格式
输入格式
第一行:两个整数n,m,分别表示点数和边数
接下来m行:每行三个整数u,v,w,表示u和v之间连一条边权为w的双向边。
输出格式
一行:一个可行的路径,如果不存在这种路径输出-1
2<=n<=105,0<=m<=105
题解:
没啥说的了,算法都给你写到题目名称,就是加个前缀数组记录一下路径而已。
直接上代码吧。哪不会去学哪。
(因为CF当天炸了,所以这份代码交上去没给评测结果,大约是对的。错了的话会再改,大家放心抄借鉴)
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=1e5+5;
int n,m;
int tot,head[maxn],nxt[maxn<<1],to[maxn<<1],val[maxn<<1],dist[maxn];
int pre[maxn],ans[maxn],cnt;
bool v[maxn];
priority_queue<pair<int,int> >q;
void add(int x,int y,int z)
{
to[++tot]=y;
nxt[tot]=head[x];
val[tot]=z;
head[x]=tot;
}
void dijkstra()
{
memset(dist,127,sizeof(dist));
dist[1]=0;
q.push(make_pair(0,1));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(v[x])
continue;
v[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(dist[y]>dist[x]+val[i])
{
dist[y]=dist[x]+val[i];
pre[y]=x;
q.push(make_pair(-dist[y],y));
}
}
}
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
dijkstra();
int pos=n;
while(pos)
{
ans[++cnt]=pos;
pos=pre[pos];
}
if(ans[cnt]!=1)
{
puts("-1");
return 0;
}
for(int i=cnt;i>=1;i--)
printf("%lld ",ans[i]);
return 0;
}