hdu2586(LCA模板)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

还是要多练习,不够熟练。。

可以一看:http://blog.csdn.net/nameofcsdn/article/details/52230548

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 const int  maxn=40010;
  8 
  9 int first[maxn<<1],node[maxn<<1],dep[maxn<<1],dp[maxn<<1][25];
 10 int dis[maxn];
 11 int head[maxn];
 12 int vis[maxn];
 13 int tot,cnt;
 14 
 15 struct edge
 16 {
 17     int v,w,nex;
 18 }e[maxn<<1];
 19 
 20 void add(int u,int v,int w)
 21 {
 22     e[cnt].v=v;
 23     e[cnt].w=w;
 24     e[cnt].nex=head[u];
 25     head[u]=cnt++;
 26 }
 27 int n,m;
 28 int u,v,w;
 29 void init()
 30 {
 31     for(int i=0;i<=n;i++)
 32     {
 33         head[i]=-1;
 34         vis[i]=0;
 35     }
 36     cnt=tot=0;
 37 }
 38 void dfs(int u,int d,int w)
 39 {
 40     tot++;
 41     vis[u]=1;
 42     first[u]=tot;
 43     node[tot]=u;
 44     dep[tot]=d;
 45     for(int i=head[u];i!=-1;i=e[i].nex) if(!vis[e[i].v])
 46     {
 47         dis[e[i].v]=w+e[i].w;
 48         dfs(e[i].v,d+1,dis[e[i].v]);
 49         tot++;
 50         node[tot]=u;
 51         dep[tot]=d;
 52     }
 53 
 54 }
 55 void RMQ_INIT(int n)
 56 {
 57     int k=log2(n);
 58     for(int i=1;i<=n;i++)
 59         dp[i][0]=i;
 60     for(int j=1;j<=k;j++)
 61         for(int i=1;i+(1<<j)-1<=n;i++)
 62     {
 63         int a=dp[i][j-1];
 64         int b=dp[i+(1<<j-1)][j-1];
 65         if(dep[a]<dep[b]) dp[i][j]=a;
 66         else dp[i][j]=b;
 67     }
 68 }
 69 int rmq(int x,int y)
 70 {
 71     int k=log2(y-x+1);
 72     int a=dp[x][k];
 73     int b=dp[y-(1<<k)+1][k];
 74     if(dep[a]<dep[b]) return a;
 75     return b;
 76 }
 77 
 78 int lca(int a,int b)
 79 {
 80     int x=first[a];
 81     int y=first[b];
 82     int k;
 83     if(x>y) swap(x,y);
 84     k=rmq(x,y);
 85     return node[k];
 86 }
 87 int main()
 88 {
 89     int t;
 90     scanf("%d",&t);
 91     while(t--)
 92     {
 93         scanf("%d%d",&n,&m);
 94         init();
 95         for(int i=1;i<n;i++)
 96         {
 97             scanf("%d%d%d",&u,&v,&w);
 98             add(u,v,w);
 99             add(v,u,w);
100         }
101 
102         dfs(1,1,0);  //任意一点当作根即可  
103         RMQ_INIT(tot);
104         while(m--)
105         {
106             scanf("%d%d",&u,&v);
107             printf("%d\n",dis[u]+dis[v]-2*dis[lca(u,v)]);
108         }
109     }
110 }

 

posted @ 2017-04-16 16:33  yijiull  阅读(111)  评论(0编辑  收藏  举报