CF20C Dijkstra?

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;
}
原文地址:https://www.cnblogs.com/fusiwei/p/14016339.html