#dijkstra,二叉堆#洛谷 5060 旅行

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/89066627

题目

找出一条最短路径,使答案为 P P 的倍数


分析

那么要用 d i s [ x ] [ w ] dis[x][w] 表示走到第 x x 个点时最短路径 mod p p 为w的最短路径,那么其实只需要一个dijkstra+堆优化即可,但是毒瘤出题人卡STL,于是手写堆,但是我太菜了,总是T掉一个点,所以只能开O2了。


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
typedef long long ll;
struct node{int y; ll w; int next;}e[200011];
pair<ll,int>heap[2500001]; ll dis[50001][51]; bool v[51][50001];
int cnt,pre[50001][51],pis[50001][51],k=1,ls[50001],n,m,p,s,t;
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
inline void Push(pair<ll,int>d){
    heap[++cnt]=d;
    rr int x=cnt;
    while (x>1){
        if (heap[x>>1]>heap[x])
            swap(heap[x>>1],heap[x]),x>>=1;
        else return;
    }
}
inline void Pop(){
    heap[1]=heap[cnt--];
    rr int x=1;
    while ((x<<1)<=cnt){
        rr int y=x<<1;
        if (y<cnt&&heap[y+1]<heap[y]) ++y;
        if (heap[y]<heap[x]) swap(heap[y],heap[x]),x=y;
        else return;
    }
}
inline void print(int x,int y){
    if (!pre[x][y]) return;
    print(pre[x][y],pis[x][y]);
    printf("%d->",pre[x][y]);
}
signed main(){
    n=iut(); m=iut(); p=iut(); s=iut(); t=iut();
    for (rr int i=1;i<=m;++i){
        rr int x=iut(),y=iut(),w=iut();
        e[++k]=(node){y,w,ls[x]}; ls[x]=k;
    }
    memset(dis,127,sizeof(dis));
    dis[s][0]=0; heap[++cnt]=make_pair(0ll,s);
    while (cnt){
        rr ll now1=heap[1].first; rr int x=heap[1].second; Pop();
        if (now1%p==0&&x==t) break;
        v[now1%p][x]=1;
        for (rr int i=ls[x];i;i=e[i].next){
            rr ll now=dis[x][now1%p]+e[i].w;
            if (now<dis[e[i].y][now%p]){
                pre[e[i].y][now%p]=x;
                pis[e[i].y][now%p]=now1%p;
                dis[e[i].y][now%p]=now;
                if (!v[now%p][e[i].y])
                    Push(make_pair(now,e[i].y));
            }
        }
    }
    if (dis[t][0]==dis[0][0]) return !printf("jjc fails in travelling");
    printf("%lld\n",dis[t][0]);
    print(t,0); return !printf("%d",t);
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/89066627