首页 > 其他分享 >G. Bicycles

G. Bicycles

时间:2023-12-29 16:11:07浏览次数:43  
标签:city Slavic dist int leq Bicycles bike

G. Bicycles

All of Slavic's friends are planning to travel from the place where they live to a party using their bikes. And they all have a bike except Slavic. There are $n$ cities through which they can travel. They all live in the city $1$ and want to go to the party located in the city $n$. The map of cities can be seen as an undirected graph with $n$ nodes and $m$ edges. Edge $i$ connects cities $u_i$ and $v_i$ and has a length of $w_i$.

Slavic doesn't have a bike, but what he has is money. Every city has exactly one bike for sale. The bike in the $i$-th city has a slowness factor of $s_{i}$. Once Slavic buys a bike, he can use it whenever to travel from the city he is currently in to any neighboring city, by taking $w_i \cdot s_j$ time, considering he is traversing edge $i$ using a bike $j$ he owns.

Slavic can buy as many bikes as he wants as money isn't a problem for him. Since Slavic hates traveling by bike, he wants to get from his place to the party in the shortest amount of time possible. And, since his informatics skills are quite rusty, he asks you for help.

What's the shortest amount of time required for Slavic to travel from city $1$ to city $n$? Slavic can't travel without a bike. It is guaranteed that it is possible for Slavic to travel from city $1$ to any other city.

Input

The first line contains a single integer $t$ ($1 \leq t \leq 100$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two space-separated integers $n$ and $m$ ($2 \leq n \leq 1000$; $n - 1 \leq m \leq 1000$) — the number of cities and the number of roads, respectively.

The $i$-th of the following $m$ lines each contain three integers $u_i$, $v_i$, $w_i$ ($1 \le u_i, v_i \le n$, $u_i \neq v_i$; $1 \leq w_i \leq 10^5$), denoting that there is a road between cities $u_i$ and $v_i$ of length $w_i$. The same pair of cities can be connected by more than one road.

The next line contains $n$ integers $s_1, \ldots, s_n$ ($1 \leq s_i \leq 1000$) — the slowness factor of each bike.

The sum of $n$ over all test cases does not exceed $1000$, and the sum of $m$ over all test cases does not exceed $1000$.

Additional constraint on the input: it is possible to travel from city $1$ to any other city.

Output

For each test case, output a single integer denoting the shortest amount of time Slavic can reach city $n$ starting from city $1$.

Example

input

3
5 5
1 2 2
3 2 1
2 4 5
2 5 7
4 5 1
5 2 1 3 3
5 10
1 2 5
1 3 5
1 4 4
1 5 8
2 3 6
2 4 3
2 5 2
3 4 1
3 5 8
4 5 2
7 2 8 4 1
7 10
3 2 8
2 1 4
2 5 7
2 6 4
7 1 2
4 3 5
6 4 2
6 7 1
6 7 4
4 5 9
7 6 5 4 3 2 1

output

19
36
14

 

解题思路

  由于必须要有车才可以移动,因此在到达任意节点时必然骑着第 $1 \sim n$ 中的一辆车。把这些车看作是一种状态,就可以考虑 dp 了。

  定义 $f(u, j)$ 表示从 $1$ 到 $u$ 且到达 $u$ 时骑的是第 $j$ 辆车的所有路径中权重的最小值。$f(u, v)$ 可以转移到与 $u$ 相邻的节点 $v_i$,并且可以骑着原来的第 $j$ 辆车或第 $u$ 辆车来到达 $v_i$,如下图:

  因此状态转移方程就是:

\begin{array}{l}
f(u,j) + s_j \cdot w_i \to f(v_i, j) \\
f(u,j) + s_u \cdot w_i \to f(v_i,u)
\end{array}

  容易发现状态转移的过程中会出现环,因此得到的不是一个拓扑图,但每条边的权重 $s_x \cdot w_i$ 都是非负的,因此可以对这个跑 Dijkstra 来求得每个状态的最小权重。其中初始状态为 $f(1,1) = 0$,最后答案是 $\min\limits_{1 \leq j \leq n}{ \left\{ f(n,j) \right\} }$。

  AC 代码如下,时间复杂度为 $O\left( \left( nm + n^2 \right) \log{nm} \right)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 1010, M = N * 2;

int w[N];
int head[N], e[M], wt[M], ne[M], idx;
LL dist[N][N];
bool vis[N][N];

void add(int u, int v, int w) {
    e[idx] = v, wt[idx] = w, ne[idx] = head[u], head[u] = idx++;
}

void solve() {
    int n, m;
    scanf("%d %d", &n, &m);
    idx = 0;
    memset(head, -1, sizeof(head));
    while (m--) {
        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++) {
        scanf("%d", w + i);
    }
    memset(dist, 0x3f, sizeof(dist));
    dist[1][1] = 0;
    priority_queue<tuple<LL, int, int>> pq;
    pq.push(make_tuple(0, 1, 1));
    memset(vis, 0, sizeof(vis));
    while (!pq.empty()) {
        int x = get<1>(pq.top()), y = get<2>(pq.top());
        pq.pop();
        if (vis[x][y]) continue;
        vis[x][y] = true;
        for (int i = head[x]; i != -1; i = ne[i]) {
            if (dist[e[i]][y] > dist[x][y] + w[y] * wt[i]) {
                dist[e[i]][y] = dist[x][y] + w[y] * wt[i];
                pq.push(make_tuple(-dist[e[i]][y], e[i], y));
            }
            if (dist[e[i]][x] > dist[x][y] + w[x] * wt[i]) {
                dist[e[i]][x] = dist[x][y] + w[x] * wt[i];
                pq.push(make_tuple(-dist[e[i]][x], e[i], x));
            }
        }
    }
    LL ret = 1e18;
    for (int i = 1; i <= n; i++) {
        ret = min(ret, dist[n][i]);
    }
    printf("%lld\n", ret);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 918 (Div. 4) Editorial:https://codeforces.com/blog/entry/123952

标签:city,Slavic,dist,int,leq,Bicycles,bike
From: https://www.cnblogs.com/onlyblues/p/17935123.html

相关文章