#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define rap(i, a, n) for(int i=a; i<=n; i++) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 2 * 1e5 + 10, INF = 0x7fffffff; LL n, m, cnt1, cnt2, c; LL head1[maxn], head2[maxn], f[maxn], vis[maxn], bz[maxn]; LL dis[50][maxn], d[maxn]; LL res[maxn]; vector<LL> se; struct node { LL u, v, w, next; }Node[maxn]; struct edge { LL u, v, id, next; }Edge[maxn]; void add1_(LL u, LL v, LL w) { Node[cnt1].u = u; Node[cnt1].v = v; Node[cnt1].w = w; Node[cnt1].next = head1[u]; head1[u] = cnt1++; } void add1(LL u, LL v, LL w) { add1_(u, v, w); add1_(v, u, w); } void add2_(LL u, LL v, LL id) { Edge[cnt2].u = u; Edge[cnt2].v = v; Edge[cnt2].id = id; Edge[cnt2].next = head2[u]; head2[u] = cnt2++; } void add2(LL u, LL v, LL id) { add2_(u, v, id); add2_(v, u, id); } LL find(LL x) { return f[x]==x?x:(f[x] = find(f[x])); } LL lca(LL u, LL deep, LL root) { f[u] = u; d[u] = deep; vis[u] = root; // 标记属于的树 for(LL i=head1[u]; i!=-1; i=Node[i].next) { node e = Node[i]; if(vis[e.v] == -1) { bz[i/2] = 1; lca(e.v, deep+e.w, root); f[e.v] = u; } } for(LL i=head2[u]; i!=-1; i=Edge[i].next) { edge e = Edge[i]; if(vis[e.v] == root) //判断另一个结点是不是和u属于一个树 { LL k = find(e.v); //寻找最近公共祖先 res[e.id] = d[u] + d[e.v] - 2*d[k]; } } } void spfa(LL s, LL id) { for(LL i=0; i<=n; i++) dis[id][i] = INF; mem(vis, 0); queue<LL> Q; Q.push(s); vis[s] = 1; dis[id][s] = 0; while(!Q.empty()) { LL u = Q.front(); Q.pop(); vis[u] = 0; for(LL i=head1[u]; i!=-1; i=Node[i].next) { node e = Node[i]; if(dis[id][e.v] > dis[id][u] + e.w) { dis[id][e.v] = dis[id][u] + e.w; if(!vis[e.v]) { Q.push(e.v); vis[e.v] = 1; } } } } } void init() { mem(head1, -1); mem(head2, -1); mem(res, -1); mem(vis, -1); cnt1 = cnt2 = 0; } int main() { cin >> n >> m; init(); rap(i, 1, m) { LL u, v, w; scanf("%lld%lld%lld", &u, &v, &w); add1(u, v, w); } cin >> c; for(LL i=1; i<=c; i++) { LL u, v; scanf("%lld%lld", &u, &v); add2(u, v, i); } for(LL i=1; i<=n; i++) if(vis[i] == -1) lca(i, 0, i); mem(vis, -1); for(LL i=0; i<cnt1; i++) { if(!bz[i/2]) { if(vis[Node[i].u] == -1) se.push_back(Node[i].u), vis[Node[i].u] = 1; if(vis[Node[i].v] == -1) se.push_back(Node[i].v), vis[Node[i].v] = 1; } } for(LL i=0; i<se.size(); i++) { // cout << se[i] << endl; spfa(se[i], i); } for(LL i=1; i<=c; i++) { for(LL j=0; j<se.size(); j++) res[i] = min(res[i], dis[j][Edge[i*2-1].u] + dis[j][Edge[i*2-1].v]); printf("%lld\n", res[i]); } return 0; }
The Shortest Statement
原文地址:https://www.cnblogs.com/WTSRUVF/p/9689559.html
时间: 2024-10-09 17:25:12