zoukankan      html  css  js  c++  java
  • bzoj5047 [Lydsy1709月赛]空间传送装置 最短路

    题目传送门

    https://lydsy.com/JudgeOnline/problem.php?id=5047

    题解

    题目中没有说可以停留在一个点等待。问了别人才知道停留是可以的。

    那么既然停留是可以的,越先到达一个点肯定是越好的,所以一般的最短路算法依然是对的。

    那么我们如果当前的这个点是 (u),要通过装置 (w)(dis[u]) 时刻往后到达点 (v)

    可以发现,对于第 (i) 个装置,第 (t) 秒和第 (t+c_ik) 秒没有区别。所以一个装置所用时间只取决于 (t mod c_i)。同时,根据上面的结论,我们需要求出这个东西的后缀最大值。可以通过求出前 (2c_i) 个值中的后缀最大值来维护。


    代码如下:

    #include<bits/stdc++.h>
    
    #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
    #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define fi first
    #define se second
    #define pb push_back
    
    template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
    template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
    
    typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
    
    template<typename I> inline void read(I &x) {
    	int f = 0, c;
    	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    	x = c & 15;
    	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    	f ? x = -x : 0;
    }
    
    const int N = 100000 + 7;
    const int M = 50 + 7;
    const int S = 2000 + 7;
    const int E = 200000 + 7;
    const int INF = 0x3f3f3f3f;
    
    int n, m, s, e;
    int c[M], f[M][S << 1];
    int dis[N], vis[N];
    std::priority_queue<pii, std::vector<pii>, std::greater<pii> > q;
    
    struct Edge { int to, ne, w; } g[E]; int head[N], tot;
    inline void addedge(int x, int y, int z) { g[++tot].to = y, g[tot].w = z, g[tot].ne = head[x], head[x] = tot; }
    inline void adde(int x, int y, int z) { addedge(x, y, z), addedge(y, x, z); }
    
    inline void dijkstra() {
    	memset(dis, 0x3f, sizeof(dis));
    	dis[1] = s; q.push(pii(dis[1], 1));
    	while (!q.empty()) {
    		int x = q.top().se; q.pop();
    		if (vis[x]) continue;
    		vis[x] = 1;
    		for fec(i, x, y) if (smin(dis[y], dis[x] + f[g[i].w][dis[x] % c[g[i].w]])) q.push(pii(dis[y], y));
    	}
    }
    
    inline void work() {
    	dijkstra();
    	for (int i = 2; i <= n; ++i) printf("%d
    ", dis[i] == INF ? -1 : dis[i] - s);
    }
    
    inline void init() {
    	read(n), read(m), read(s), read(e);
    	for (int i = 1; i <= m; ++i) {
    		int a, b, &c = ::c[i], d;
    		read(a), read(b), read(c), read(d);
    		f[i][c << 1] = INF;
    		for (int j = (c << 1) - 1; ~j; --j) f[i][j] = std::min((a * j + b) % c + d, f[i][j + 1] + 1);
    	}
    	int x, y, z;
    	for (int i = 1; i <= e; ++i) read(x), read(y), read(z), addedge(x, y, z);
    }
    
    int main() {
    #ifdef hzhkk
    	freopen("hkk.in", "r", stdin);
    #endif
    	init();
    	work();
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    toj 2819 Travel
    toj 2807 Number Sort
    zoj 2818 Prairie dogs IV
    zoj 1276 Optimal Array Multiplication Sequence
    toj 2802 Tom's Game
    toj 2798 Farey Sequence
    toj 2815 Searching Problem
    toj 2806 Replace Words
    toj 2794 Bus
    css截取字符
  • 原文地址:https://www.cnblogs.com/hankeke/p/bzoj5047.html
Copyright © 2011-2022 走看看