解题思路:Tarjan离线处理
一篇介绍LCA的很好的博客:http://www.cppblog.com/menjitianya/archive/2015/12/10/212447.html
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 10005; struct Edge { int k,next,cost; }edge[maxn<<1]; struct Ask { int k,next,id; }ask[maxn<<1]; int n,m,c,cnt1,cnt2,pre[maxn],head[maxn]; int color[maxn],ans[maxn],dis[maxn],fa[maxn]; bool vis[maxn]; int find(int x) { if(fa[x] == x) return x; else return fa[x] = find(fa[x]); } void addedge(int u,int v,int cost) { edge[cnt1].k = v; edge[cnt1].cost = cost; edge[cnt1].next = pre[u]; pre[u] = cnt1++; } void addask(int u,int v,int id) { ask[cnt2].id = id; ask[cnt2].k = v; ask[cnt2].next = head[u]; head[u] = cnt2++; } void Tarjan(int u,int root,int len) { vis[u] = true; fa[u] = u; dis[u] = len; for(int i = pre[u]; i != -1; i = edge[i].next) { int v = edge[i].k; if(vis[v]) continue; Tarjan(v,root,len + edge[i].cost); fa[v] = u; } color[u] = root; for(int i = head[u]; i != -1; i = ask[i].next) { int v = ask[i].k; if(color[v] == root) { int ancestor = find(v); ans[ask[i].id] = dis[u] + dis[v] - 2*dis[ancestor]; } } } int main() { int u,v,cost; while(scanf("%d%d%d",&n,&m,&c)!=EOF) { memset(pre,-1,sizeof(pre)); memset(head,-1,sizeof(head)); cnt1 = cnt2 = 0; for(int i = 1; i <= m; i++) { scanf("%d%d%d",&u,&v,&cost); addedge(u,v,cost); addedge(v,u,cost); } for(int i = 1; i <= c; i++) { scanf("%d%d",&u,&v); addask(u,v,i); addask(v,u,i); } memset(vis,false,sizeof(vis)); memset(color,0,sizeof(color)); memset(ans,-1,sizeof(ans)); for(int i = 1; i <= n; i++) if(vis[i] == false) Tarjan(i,i,0); for(int i = 1; i <= c; i++) { if(ans[i] == -1) printf("Not connected\n"); else printf("%d\n",ans[i]); } } return 0; }