ことりのおやつ(小鸟的点心)link
思路:
SPFA
先把时间预处理一下,
定义一个时间撮last为最早封路的时间,
只需在spfa更换路径的时候再加个判断,很容易想到。
有一个坑的地方,在到终点的时候不用考虑雪的深度,特判一下就好。
#include <bits/stdc++.h>
#define inf 1e9
using namespace std;
const int N = 5e5 + 10;
struct node { int to, next, v;} e[2 * N];
int n, m, s, t, g, q, last[N], head[N], cnt, h[N], l[N], dis[N];
bool vis[N];
void add(int x, int y, int z)
{
e[++cnt] = (node) {y, head[x], z};
head[x] = cnt;
}
bool spfa()
{
queue <int> q;
memset(dis, 127 / 3, sizeof(dis));
q.push(s);
dis[s] = 0;
vis[s] = 1;
while(!q.empty())
{
int tx = q.front();
q.pop();
vis[tx] = 0;
for(int i = head[tx]; i; i = e[i].next)
{
int v = e[i].to;
if((dis[v] > dis[tx] + e[i].v && v != t && dis[tx] + e[i].v < last[v]) || (dis[tx] + e[i].v < dis[v] && v == t)) //或者后面一个条件,到达终点,只要判断新的路径是否更短即可
{
dis[v] = dis[tx] + e[i].v;
if(!vis[v]) q.push(v), vis[v] = 1;
}
}
}
//cout<<dis[t]<<endl;
//cout<<dis[0]<<endl;
return !(dis[t] == dis[0]);
}
int main()
{
scanf("%d%d%d%d%d%d", &n, &m, &s, &t, &g, &q);
for(int i = 1; i <= n; i++) scanf("%d%d", &h[i], &l[i]);
for(int i = 1; i <= m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
for(int i = 1; i <= n; i++)
{
if(!q) last[i] = inf + 1;
else last[i] = int(double(l[i] - h[i]) / double(q));
}
if(spfa() && dis[t] <= g) printf("%d\n", dis[t]);
else printf("wtnap wa kotori no oyatsu desu!\n");
return 0;
}