您的位置:首页 > 其它

最近公共祖先(lca) hdu 2586

2015-05-20 10:55 405 查看

hdu 2586 How far away ?

题目大意:给定n-1条边构成一棵树,无向的;和m个询问,对于每一个询问按顺序回答。

结题思路:lca算法算出最近公共祖先,然后dis[u]+dis[v]-2*dis[father](father是u,v的最近公共祖先),小trick是在构造询问树的时候把权值设成询问对应的输入顺序

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int maxn=40000+10;
struct node
{
int v,w,next;
}e[maxn<<1],q[maxn<<1];
int ehead[maxn],qhead[maxn],vis[maxn],fa[maxn],dis[maxn],ans[maxn];
int eT,qT;
int n,m;
void build(node *ed,int *head,int &T,int u,int v,int w)
{
ed[T].v=v;
ed[T].w=w;
ed[T].next=head[u];
head[u]=T++;
}
void init()
{
memset(ans,0,sizeof(ans));
memset(dis,0,sizeof(dis));
memset(ehead,-1,sizeof(ehead));
memset(qhead,-1,sizeof(qhead));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
fa[i]=i;
eT=qT=0;
int u,v,w;
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&w);
build(e,ehead,eT,u,v,w);
build(e,ehead,eT,v,u,w);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
build(q,qhead,qT,u,v,i);
build(q,qhead,qT,v,u,i);
}
}
int getf(int x)
{
while(x!=fa[x])
{
fa[x]=getf(fa[x]);
x=fa[x];
}
return x;
}
void dfs(int u)
{
vis[u]=1;
for(int i=ehead[u];~i;i=e[i].next)
{
int v=e[i].v;
if(!vis[v])
{
dis[v]=dis[u]+e[i].w;
dfs(v);
fa[v]=u;
}
}
for(int i=qhead[u];~i;i=q[i].next)
{
int v=q[i].v;
if(vis[v])
{
ans[q[i].w]=dis[u]+dis[v]-2*dis[getf(v)];
}
}
}
int main()
{
int kase;
//freopen("in.txt","r",stdin);
scanf("%d",&kase);
while(kase--)
{
scanf("%d%d",&n,&m);
init();
dfs(1);
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: