zoukankan      html  css  js  c++  java
  • 【最近公共祖先】【树链剖分】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
    ",ans);
    	return 0;
    }
  • 相关阅读:
    MySql 定时完成备份
    smarty插件
    PHP字符串函数小结
    eclipse搭建maven project的spring4 spring mvc mybatis
    C#数组存入引用类型
    C#数组
    【转】Linus:利用二级指针删除单向链表
    [LeetCode] Reverse Linked List II
    ubuntu配置git
    mint安装Node.js
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4341185.html
Copyright © 2011-2022 走看看