我是用LCM的方法来做的。
即通过倍增法找到两个点的最小公共祖先。
在维护p数组的同时,一边维护一个记录边长的数组w
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define ll long long
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int MAXN = 1e5+5;
const int LOGN = log(MAXN)/log(2)+5;
int z,m,n;
int fa[MAXN],wfa[MAXN],anc[MAXN];
int lg[MAXN];
int L[MAXN];
int p[MAXN][LOGN];
ll w[MAXN][LOGN];
bool vis[MAXN];
vector<int> e[MAXN];
vector<ll> we[MAXN];
long long res;
void init_lg(){
lg[1]=0;
for(int i=2;i<MAXN;i++) lg[i]=lg[i-1]+((1<<(lg[i-1]+1))==i);
}
void dfs(int xanc,int x,int prev){
for(int i=0;i<e[x].size();i++){
int &u=e[x][i];
if(u==prev) continue;
L[u]=L[x]+1;
fa[u]=x;
wfa[u]=we[x][i];
anc[u]=xanc;
vis[u]=1;
dfs(xanc,u,x);
}
}
void preprocess(int n){
for(int i=1;i<=n;i++)
for(int j=0;j<=lg[n];j++)w[i][j]=p[i][j]=-1;
for(int i=1;i<=n;i++){
p[i][0]=fa[i]; w[i][0]=wfa[i];
}
for(int j=1;j<=lg[n];j++)
for(int i=1;i<=n;i++)
if(p[i][j-1]!=-1){
p[i][j]=p[p[i][j-1]][j-1];
w[i][j] = w[i][j-1] + w[p[i][j-1]][j-1];
//cout<<"checkwij"<<i<<','<<j<<','<<w[i][j]<<endl;
}
}
int LCA(int u,int v){
if(L[u]<L[v]) swap(u,v);
int log = lg[L[u]];
for(int i=log;i>=0;i--)
if(L[u]-(1<<i)>=L[v]){
res+=w[u][i];
u=p[u][i];
}
if(u==v) return u;
for(int i=log;i>=0;i--)
if(p[u][i]!=-1&&p[u][i]!=p[v][i]){
res+=w[u][i];
//cout<<"v["<<w[u][i]<<endl;
u=p[u][i];
res+=w[v][i];
//cout<<"v["<<w[v][i]<<endl;
v=p[v][i];
}
res+=wfa[u]+wfa[v];
return fa[u];
}
inline int query(int u,int v){
if(anc[u]!=anc[v]) return -1;
res = 0;
LCA(u,v);
return res;
}
inline void add_edge(int u,int v,int c){
e[u].push_back(v);
e[v].push_back(u);
we[u].push_back(c);
we[v].push_back(c);
}
int main(){
int q,k;
int u,v;
init_lg();
while(cin>>n>>m>>q){
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++){
cin>>u>>v>>k;
add_edge(u,v,k);
}
for(int i=1;i<=n;i++){
if(vis[i]) continue;
vis[i]=1;
anc[i]=i;
dfs(i,i,-1);
}
preprocess(n);
while(q--){
cin>>u>>v;
if(query(u,v)==-1) cout<<"Not connected"<<endl;
else cout<<res<<endl;
}
for(int i=1;i<=n;i++){
e[i].clear();
we[i].clear();
}
}
}