【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行

树链剖分求lca模板。O(log(n)),就是不倍增嘛~

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 30001
int n,m,ans;
int v[N<<1],next[N<<1],first[N],en;
void AddEdge(int U,int V)
{
	v[++en]=V;
	next[en]=first[U];
	first[U]=en;
}
int fa[N],dep[N],top[N],son[N],siz[N],tot;
void dfs(int U)
{
	siz[U]=1;
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U])
	    {
	      fa[v[i]]=U;
	      dep[v[i]]=dep[U]+1;
	      dfs(v[i]);
	      siz[U]+=siz[v[i]];
	      if(siz[v[i]]>siz[son[U]])
	        son[U]=v[i];
	    }
}
void df2(int U)
{
	if(son[U])
	  {
	  	top[son[U]]=top[U];
	  	df2(son[U]);
	  }
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U]&&v[i]!=son[U])
	    {
	      top[v[i]]=v[i];
	      df2(v[i]);
	    }
}
int lca(int U,int V)
{
	while(top[U]!=top[V])
	  {
	  	if(dep[top[U]]<dep[top[V]])
	  	  swap(U,V);
	  	U=fa[top[U]];
	  }
	if(dep[U]>dep[V])
	  swap(U,V);
	return U;
}
int main()
{
	int x,y;
	scanf("%d",&n);
	for(int i=1;i<n;++i)
	  {
	  	scanf("%d%d",&x,&y);
	  	AddEdge(x,y);
	  	AddEdge(y,x);
	  }
	top[1]=1;
	dfs(1);
	df2(1);
	scanf("%d%d",&m,&x);
    for(int i=2;i<=m;i++)
      {
        scanf("%d",&y);
        ans+=(dep[x]+dep[y]-(dep[lca(x,y)]<<1));
        x=y;
      }
    printf("%d\n",ans);
	return 0;
}
posted @ 2015-03-16 10:32  AutSky_JadeK  阅读(198)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト