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

思路

定义 \(d_{i,j}\) 表示从 \(1\) 走到 \(i\),并且满足 \(t \bmod k = j\) 的最小的符合题意的 \(t\)

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

当要计算一条 \(u \to v\) 的边 \(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;  
}  
posted @ 2024-06-26 12:37  WBIKPS  阅读(54)  评论(0)    收藏  举报