码迷,mamicode.com
首页 > 其他好文 > 详细

The Shortest Statement

时间:2020-05-09 19:04:20      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:mat   define   struct   first   ted   c++   com   tin   The   

题目

You are given a weighed undirected connected graph, consisting of \(n\) vertices and \(m\) edges.

You should answer \(q\) queries, the \(i\)-th query is to find the shortest distance between vertices \(u_i\) and \(v_i\).

Input

The first line contains two integers \(n\) and \(m (1≤n,m≤10^5,m?n≤20)\) — the number of vertices and edges in the graph.

Next \(m\) lines contain the edges: the \(i\)-th edge is a triple of integers \(v_i,u_i,d_i (1≤u_i,v_i≤n,1≤d_i≤10^9,u_i≠v_i)\). This triple means that there is an edge between vertices \(u_i\) and \(v_i\) of weight \(d_i\). It is guaranteed that graph contains no self-loops and multiple edges.

The next line contains a single integer \(q (1≤q≤10^5)\) — the number of queries.

Each of the next q lines contains two integers \(u_i\) and \(v_i (1≤u_i,v_i≤n)\) — descriptions of the queries.

Pay attention to the restriction \(m?n ≤ 20\).

Output

Print \(q\) lines.

The \(i\)-th line should contain the answer to the \(i\)-th query — the shortest distance between vertices \(u_i\) and \(v_i\).

Examples

Input 1

3 3
1 2 3
2 3 1
3 1 5
3
1 2
1 3
2 3

Output 1

3
4
1

Input 2

8 13
1 2 4
2 3 6
3 4 1
4 5 12
5 6 3
6 7 8
7 8 7
1 4 1
1 8 3
2 6 9
2 7 1
4 6 3
6 8 2
8
1 5
1 7
2 3
2 8
3 7
3 4
6 8
7 8

Output 2

7
5
6
7
7
1
2
7

题解

解题思路

对于这道题,跑n遍最短路会超时的
题目中有一个特殊的条件 \(m?n ≤ 20\).
就是说这个图只比树最多多42条边
就可以根据lca和dij求最短路

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MN = 2 * 1e5 + 10;
int N, M, Q, head[MN], num = 0, v[MN], f[MN][21], dp[MN], hp[MN];
int d[50][MN], Tdis[MN];
vector<int> p;
struct Edge {
    int u, v, w, f, next;
}e[MN];
inline void add(int x, int y, int z) {
    e[num] = (Edge) {x, y, z, 0, head[x]};
    head[x] = num++;
}
void dfs(int x, int _fa) {
    v[x] = 1; dp[x] = dp[_fa] + 1;
    for(int i = head[x]; ~i; i = e[i].next) {
        int to = e[i].v;
        if(v[to]) continue;
        e[i].f = e[i ^ 1].f = 1;
        Tdis[to] = Tdis[x] + (int)e[i].w;
        f[to][0] = x;
        dfs(to, x);
    }
}
void Dij(int x, int id) {
    memset(v, 0, sizeof(v));
    d[id][x] = 0;
    priority_queue<pair<int, int> > q; q.push(make_pair(0, x));
    while(!q.empty()) {
        int p = q.top().second; q.pop();
        if(v[p]) continue;
        v[p] = 1;
        for(int i = head[p]; ~i; i = e[i].next) {
            int to = e[i].v;
            if(d[id][to] > d[id][p] + e[i].w && (!v[to]))
                d[id][to] = d[id][p] + e[i].w, q.push(make_pair(-d[id][to], to));
        }
    }
}

int lca(int x, int y) {
    if(dp[x] < dp[y]) swap(x, y);
    for(int i = 20; i >= 0; i--)
        if(dp[f[x][i]] >= dp[y]) x = f[x][i];
    if(x == y) return x;
    for(int i = 20; i >= 0; i--)
        if(f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
    return f[x][0];
}

signed main(){
    memset(head, -1, sizeof(head));
    scanf("%lld%lld", &N, &M);
    for(int i = 1; i <= M; i++) {
        int x, y, z;
        scanf("%lld%lld%lld", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }
    dfs(1, 0);
    for(int i = 0; i < num; i++)
        if(!e[i].f) {
            if(!hp[e[i].u]) p.push_back(e[i].u), hp[e[i].u] = 1;
            if(!hp[e[i].v]) p.push_back(e[i].v), hp[e[i].v] = 1;
        }
    memset(d, 0x7f, sizeof(d));
    for(int i = 0; i < p.size(); i++)
        Dij(p[i], i);
    for(int j = 1; j <= 20; j++)
        for(int i = 1; i <= N; i++)
            f[i][j] = f[f[i][j - 1]][j - 1];
    scanf("%lld", &Q);
    while(Q--) {
        int x, y;
        scanf("%lld%lld", &x, &y);
        int ans = Tdis[x] + Tdis[y] - 2 * Tdis[lca(x, y)];
        for(int i = 0; i < p.size(); i++)
            ans = min(ans, d[i][x] + d[i][y]);
        cout << ans << endl;
    }
    return 0;
}

The Shortest Statement

标签:mat   define   struct   first   ted   c++   com   tin   The   

原文地址:https://www.cnblogs.com/Z8875/p/12859030.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!