物语(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(ui≠vi,1≤ui,vi≤N,0<wi≤10^9)\),表示这条道路连接的区域和通过时间。

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

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

\(Output\)

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

\(Sample Input\)

输入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

Sample Output

输出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);
    }
}

猜你喜欢

转载自www.cnblogs.com/leiyuanze/p/12319157.html
今日推荐