[题解]P9751 [CSP-J 2023] 旅游巴士

思路

定义 di,j 表示从 1 走到 i,并且满足 tmodk=j 的最小的符合题意的 t

然后就可以直接跑一遍 Dijkstra 即可。

当要计算一条 uv 的边 w 时,如果当前时间不够无法达到 w,那么需要将时间提到第一个时间大于 w,并且模 k 相同的 x 即可。

Code

#include <bits/stdc++.h>  
#define fst first  
#define snd second  
#define re register  
  
using namespace std;  
  
typedef pair<int,int> pii;  
const int N = 1e4 + 10,M = 2e4 + 10,K = 110,inf = 0x3f3f3f3f;  
int n,m,k;  
int d[N][K];  
int idx,h[N],ne[M],e[M],w[M];  
bool vis[N][K];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline void add(int a,int b,int c){  
    ne[idx] = h[a];  
    e[idx] = b;  
    w[idx] = c;  
    h[a] = idx++;  
}  
  
inline int up(int a,int b){  
    if (a % b == 0) return a / b;  
    return a / b + 1;  
}  
  
inline int get(int x,int y){  
    if (x >= y) return x;  
    return up(y - x,k) * k + x;  
}  
  
inline void dijkstra(int s){  
    priority_queue<pii,vector<pii>,greater<pii>> q;  
    d[s][0] = 0;  
    q.push({0,s});  
    while (!q.empty()){  
        pii t = q.top();  
        q.pop();  
        int dist = t.fst % k;  
        if (vis[t.snd][dist]) continue;  
        vis[t.snd][dist] = true;  
        for (re int i = h[t.snd];~i;i = ne[i]){  
            int j = e[i],lim = w[i];  
            int ndist = (dist + 1) % k,ntim = get(t.fst,lim) + 1;  
            if (d[j][ndist] > ntim){  
                d[j][ndist] = ntim;  
                q.push({d[j][ndist],j});  
            }  
        }  
    }  
}  
  
int main(){  
    memset(h,-1,sizeof(h));  
    memset(d,inf,sizeof(d));  
    n = read();  
    m = read();  
    k = read();  
    for (re int i = 1;i <= m;i++){  
        int a,b,c;  
        a = read();  
        b = read();  
        c = read();  
        add(a,b,c);  
    }  
    dijkstra(1);  
    if (d[n][0] >= inf) puts("-1");  
    else printf("%d",d[n][0]);  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18268810

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示