标签: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\).
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\).
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\).
3 3
1 2 3
2 3 1
3 1 5
3
1 2
1 3
2 3
3
4
1
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
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;
}
标签:mat define struct first ted c++ com tin The
原文地址:https://www.cnblogs.com/Z8875/p/12859030.html