「Luogu 3946」ことりのおやつ

秋叶原共有 n 个地点,编号从 1 到 n 。每个地点在开始的时候的积雪高度为 \(h_i\)

有 m 条双向道路连接这些地点,它们的长度分别为 \(w_i\) 米。

雪太大,公共交通系统已经停摆了,所以ことり得走路回家。她走路的速度是 1m/s 。

为了方便地图的绘制,秋叶原的道路规划使得每条道路严格地连接两个不同的地点,并且不会有两条道路连接的地点相同。

每个地点都有一个极限雪高 \(l_i\) ,单位是毫米,如果到达这个地点的时候,这里的雪的高度高于li则会被困在这个点走不出去,无法成功地走到ことり家。

点心店这个地点的编号是 s ,ことり家的编号是 t 。

不考虑点心店和ことり家的雪。

ことり想在 g 秒内回到家吃点心,越快越好。如果在 g 秒之内,ことり无法到家,或者她被困在路上了,那么ことり会把 wtnap 变成她的点心( ・ 8 ・ )

Luogu

分析

这题肯定是个最短路。

对于 q = 0 的情况,直接跑一遍 Dijkstra 就好了。

扫描二维码关注公众号,回复: 8646291 查看本文章

对于其它情况,我们先求出 f[i] ,表示第 i 个点必须在 f[i] 的时间内到达,\(f[i]=\lfloor\frac{l[i]-h[i]}{q} \rfloor\) ,然后一直跑最短路,每次将 dis[i] > f[i] 的点去掉,直到没有点可以去掉或者无法到达终点,然后特判一下不合法的情况输出就好了。

这题数据是真水,我的这种方法居然还过了,虽然考试的时候因为除以了 0 ,导致 RE 只有 55pts 。

最后,有一个坑点是在终点时不用考虑雪的厚度。

代码

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100005
#define M 500005
#define il inline
#define re register
#define mp make_pair
#define INF 0x3f3f3f3f
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

template <typename T> inline void read(T &x) {
    T f = 1; x = 0; char c;
    for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
    for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x *= f;
}

struct edge {
    int to, nxt, val;
} e[M<<1];

int n, m, g, p, t;
int head[M<<1], cnt;
int f[N], dis[N];
bool vis[N], mk[N], flg = 1;

void insert(int u, int v, int w) {
    e[++cnt].to = v, e[cnt].val = w, e[cnt].nxt = head[u], head[u] = cnt;
}

void dijkstra(int s) {
    for (int i = 1; i <= n; ++i) dis[i] = INF, vis[i] = 0;
    priority_queue < pair<int, int> > q;
    q.push(mp(dis[s] = 0, s));
    while (!q.empty()) {
        int u = q.top().second;
        q.pop();
        if (vis[u]) continue;
        if (mk[u]) continue;
        vis[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to, w = e[i].val;
            if (dis[v] > dis[u] + w) {
                dis[v] = dis[u] + w;
                q.push(mp(-dis[v], v));
            }
        }
    }
}

bool check() {
    bool ok = 1;
    if (dis[t] > g) { flg = 0; return true; }
    for (int i = 1; i <= n; ++i) {
        if (mk[i]) continue;
        if (dis[i] > f[i])
            mk[i] = 1, ok = 0;
    }
    return ok;
}

int main() {
    //File("oyatsu");
    int u, v, w, h, l, s;
    read(n), read(m), read(s), read(t), read(g), read(p);
    for (int i = 1; i <= n; ++i) {
        read(h), read(l);
        if (p) f[i] = (l - h) / p;
    }
    for (int i = 1; i <= m; ++i) {
        read(u), read(v), read(w);
        insert(u, v, w), insert(v, u, w);
    }
    dijkstra(s);
    if (p == 0) {
        if (dis[t] > g) puts("wtnap wa kotori no oyatsu desu!");
        else printf("%d", dis[t]);
        return 0;
    }
    while (!check()) dijkstra(s);
    if (!flg || dis[t] > g) puts("wtnap wa kotori no oyatsu desu!");
    else printf("%d", dis[t]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hlw1/p/12202813.html