hdu 2874 Connections between cities
http://acm.hdu.edu.cn/showproblem.php?pid=2874
裸LCA,处理森林的无向图。
思路:给每棵树一个唯一的编号,查LCA的时候,判断一下是不是在同一棵树下就行了。

#include<stdio.h> #include<string.h> #include<iostream> #include<vector> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:36777216") using namespace std; const int maxn = 10005; struct node{ int to,next,w; }edge[maxn*2]; struct nd { int to,idx,next; }qes[maxn*200]; int ans[maxn*100]; int h[maxn],hh[maxn]; int vis[maxn],fa[maxn]; int dis[maxn]; int ecnt1,ecnt2; void add(int s,int t,int w) { edge[ecnt1].to = t; edge[ecnt1].w = w; edge[ecnt1].next = h[s]; h[s] = ecnt1++; } void ADD(int s,int t,int idx) { qes[ecnt2].to = t; qes[ecnt2].idx = idx; qes[ecnt2].next = hh[s]; hh[s] = ecnt2++; } int fun(int x) { if(x!=fa[x]) fa[x] = fun(fa[x]); return fa[x]; } void tarjan(int pre,int u,int root,int sum) { int i,v,x,y; dis[u] = sum; vis[u] = root; for(i = h[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(vis[v])continue; tarjan(u,v,root,sum+edge[i].w); x = fun(u); y = fun(v); if(x!=y) fa[y] = x; } for(i = hh[u]; i != -1; i = qes[i].next) { v = qes[i].to; x = qes[i].idx; if(vis[v]==root&&ans[x]<0) ans[x] = dis[u] + dis[v] - dis[fun(v)] * 2; } } int main() { int i,j,k,s,t,n,m,c,w; while(scanf("%d %d %d",&n,&m,&c)==3) { memset(h,-1,sizeof(h)); memset(hh,-1,sizeof(hh)); memset(vis,0,sizeof(vis)); memset(ans,-1,sizeof(ans)); for(i = 0; i <= n; ++ i) fa[i] = i; ecnt1 = ecnt2 = 0; for(i = 0; i < m; ++ i) { scanf("%d %d %d",&s,&t,&w); add(s,t,w); add(t,s,w); } for(i = 0; i < c; ++ i) { scanf("%d %d",&s,&t); ADD(s,t,i); ADD(t,s,i); } for(i = 1; i <= n; ++ i)if(!vis[i]) tarjan(0,i,i,0); for(i = 0; i < c; ++ i) if(ans[i]==-1) puts("Not connected"); else printf("%d\n",ans[i]); }return 0; }