物语(monogatari)

Description

某一天,少年邂逅了同病相连的IA。见面后,IA一把牵起少年的手,决定和他一起逃离部落,离开这个无法容身的是非之地。

要逃离部落,少年和IA就需要先选择一条耗时最少的路线,从而避免被部落的大人们抓到。部落可以大致分为N个区域,少年和IA在区域1,部落的出口设在区域N。此外部落还有M条连接两个区域道路。道路是无向的,没有一条道路的两端连接相同的区域,也没有两条道路所连接的两个区域完全相同。对于其中前(M−1)条道路,其通过时间是确定的,但最后一条道路,由于地理因素,通过其的时间会不断变化。

现在,少年和IA得知了在K个不同的时段里,通过第M条道路的时间,请您分别计算出在这K 个时段中逃离部落的最少时间,以帮助他们确定行动的时刻。

Input

第一行三个整数N,M,K,分别表示区域数,道路数,询问数。

接下来M−1行每行三个整数 ui,vi,wi(uivi,1ui,viN,0<wi109),表示这条道路连接的区域和通过时间。

紧接着是两个整数 ui,vi(uivi,1ui,viN),表示第M条道路连接的区域。

最后K行,每行一个正整数 xi(0<xi109),表示目前第M条道路的通过时间。

Output

输出共计K行,每行一个整数,表示对应时段逃离部落的最短时间。如果在该时段内无法逃离,输出“+Inf”。

SampleInput

输入1:

4 5 4

1 2 7

1 3 4

2 4 3

3 4 6

2 3

1

2

4

6

输入2:

4 3 1

1 2 7

1 3 4

2 3

9

SampleOutput

输出1:

8

9

10

10

输出2:

+Inf

Hint

代码(常数巨大,不得不开O)

#pragma GCC optimize(2)
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 200000 , M = 500000;
const LL INF = 1e16 + 10;
int n , m , k , h[N + 5] , vis[N + 5] , tot = 1 , u , v;
LL dis1[N + 5] , disu[N + 5] , disv[N + 5] , ans , w;
struct edge{
int to , nxt;
LL w;
}e[(M << 1) + 5];
struct node{
int id;
LL d;
bool operator < (node c) const
{
return d > c.d;
}
};
inline void add(int u , int v , int w)
{
e[++tot].to = v , e[tot].w = w , e[tot].nxt = h[u] , h[u] = tot;
}
inline LL Min(LL x , LL y) { return x < y ? x : y; };
priority_queue<node> q;
inline void dij1()
{
memset(vis , 0 , sizeof(vis));
dis1[1] = 0;
q.push((node){1 , 0});
while (!q.empty())
{
node x = q.top();
q.pop();
if (vis[x.id]) continue;
vis[x.id] = 1;
for(register int i = h[x.id]; i; i = e[i].nxt)
{
if (dis1[x.id] + e[i].w < dis1[e[i].to])
{
dis1[e[i].to] = dis1[x.id] + e[i].w;
q.push((node){e[i].to , dis1[e[i].to]});
}
}
}
}
priority_queue<node> Q;
inline void diju()
{
memset(vis , 0 , sizeof(vis));
disu[u] = 0;
Q.push((node){u , 0});
while (!Q.empty())
{
node x = Q.top();
Q.pop();
if (vis[x.id]) continue;
vis[x.id] = 1;
for(register int i = h[x.id]; i; i = e[i].nxt)
{
if (disu[x.id] + e[i].w < disu[e[i].to])
{
disu[e[i].to] = disu[x.id] + e[i].w;
Q.push((node){e[i].to , disu[e[i].to]});
}
}
}
}
priority_queue<node> QQ;
inline void dijv()
{
memset(vis , 0 , sizeof(vis));
disv[v] = 0;
QQ.push((node){v , 0});
while (!QQ.empty())
{
node x = QQ.top();
QQ.pop();
if (vis[x.id]) continue;
vis[x.id] = 1;
for(register int i = h[x.id]; i; i = e[i].nxt)
{
if (disv[x.id] + e[i].w < disv[e[i].to])
{
disv[e[i].to] = disv[x.id] + e[i].w;
QQ.push((node){e[i].to , disv[e[i].to]});
}
}
}
}
int main()
{
freopen("monogatari.in" , "r" , stdin);
freopen("monogatari.out" , "w" , stdout);
scanf("%d%d%d" , &n , &m , &k);
for(register int i = 1; i < m; i++)
{
scanf("%d%d%lld" , &u , &v , &w);
add(u , v , w) , add(v , u , w);
}
for(register int i = 1; i <= n; i++)
dis1[i] = INF , disu[i] = INF , disv[i] = INF;
scanf("%d%d" , &u , &v);
dij1() , diju() , dijv();
for(register int i = 1; i <= k; i++)
{
scanf("%lld" , &w);
ans = dis1[n];
if (dis1[u] != INF && disv[n] != INF) ans = Min(ans , dis1[u] + w + disv[n]);
if (dis1[v] != INF && disu[n] != INF) ans = Min(ans , dis1[v] + w + disu[n]);
if (ans == INF) printf("+Inf\n");
else printf("%lld\n" , ans);
}
}
posted @   leiyuanze  阅读(610)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示