标签:lca
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
题意:一棵有边权的树,问任意两点间的长度是多少。
思路:做LCA题目看到的这道题,就用LCA做了,其实只用LCA的递归部分就能做这道题了。
用一个数组dis记录根节点到每个节点的距离,则任意两节点a、b间的距离就是dis[a]+dis[b]-2*dis[lca(a,b)]。
我用vector,交G++要RE,交C++得手动扩栈才能过
LCA离线算法
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 40100 #define eps 1e-7 #define INF 0x7FFFFFFF #define LLINF 0x7FFFFFFFFFFFFFFF #define seed 1313131 #define MOD 1000000007 #define ll long long #define ull unsigned ll #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct node{ int v,w,next; }edge[4*MAXN]; int head[MAXN]; int father[MAXN]; int num[MAXN]; int ind[MAXN];//保存每个节点的入度 int vis[MAXN]; int ancestor[MAXN]; vector<int> Qes[MAXN]; map<pair<int,int>,int>mp; int query[210][2]; int cnt; int dis[MAXN]; void add_edge(int u,int v,int w){ edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt++; } void init(int n){ cnt = 0; mp.clear(); for(int i=1;i<=n;i++){ dis[i] = 0; head[i] = -1; num[i] = 1; father[i] = i; ind[i] = 0; ancestor[i] = 0; Qes[i].clear(); } } int Find(int x){ int t = x; while(t!=father[t]) t = father[t]; int k = x; while(k!=t){ int temp = father[k]; father[k] = t; k = temp; } return t; } int Union(int x,int y){ int a=Find(x); int b=Find(y); if(a==b) return 0; else if(num[a]<=num[b]){ father[a] = b; num[b] += num[a]; } else{ father[b] = a; num[a] += num[b]; } return 1; } void LCA(int u,int len){ int i,j; ancestor[u]=u; dis[u] = len; for(i=head[u];i!=-1;i=edge[i].next){ int v = edge[i].v; LCA(v,len+edge[i].w); Union(u,v); ancestor[Find(u)] = u; } vis[u] = 1; int _size = Qes[u].size(); for(i=0;i<_size;i++){ if(vis[Qes[u][i]]){ pair<int,int> p; if(u>Qes[u][i]) p = make_pair(Qes[u][i],u); else p = make_pair(u,Qes[u][i]); mp[p] = ancestor[Find(Qes[u][i])]; } } } int main(){ int t,i,j,n,q; int a,b,c; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&q); init(n); for(i=1;i<n;i++){ scanf("%d%d%d",&a,&b,&c); add_edge(a,b,c); ind[b]++; } for(i=0;i<q;i++){ scanf("%d%d",&a,&b); Qes[a].push_back(b); Qes[b].push_back(a); query[i][0] = min(a,b); query[i][1] = max(a,b); } for(i=1;i<=n;i++){ if(ind[i]==0){ LCA(i,0); break; } } for(i=0;i<q;i++){ pair<int,int> p = make_pair(query[i][0],query[i][1]); printf("%d\n",dis[query[i][0]]+dis[query[i][1]]-2*dis[mp[p]]); } printf(""); } return 0; }
HDU--2586--How far away ?【LCA】
标签:lca
原文地址:http://blog.csdn.net/zzzz40/article/details/39299609