codevs 2370 小机房的树

题目链接:http://codevs.cn/problem/2370/

题解:

  裸LCA,注意结点是从0开始编号

Tarjan

 1 #include<cstdio>
 2 #define MAXN 50010
 3 #define MAXQ 75010
 4 int n,Q,heade[MAXN],headq[MAXN],fa[MAXN],lca[MAXQ],dis[MAXN],cnt;
 5 bool vis[MAXN];
 6 struct edge
 7 {
 8     int v,next,val;
 9 }e[MAXN*2];
10 struct query
11 {
12     int u,v,next;
13 }q[MAXQ*2];
14 void adde(int x,int y,int z)
15 {
16     e[++cnt].v=y;
17     e[cnt].next=heade[x];
18     heade[x]=cnt;
19     e[cnt].val=z;
20 }
21 void addq(int x,int y)
22 {
23     q[++cnt].u=x;
24     q[cnt].v=y;
25     q[cnt].next=headq[x];
26     headq[x]=cnt;
27 }
28 int getfa(int x)
29 {
30     return fa[x]=x==fa[x]?x:getfa(fa[x]);
31 }
32 int getdis(int i)
33 {
34     return dis[q[i<<1].u]+dis[q[i<<1].v]-2*dis[lca[i]];
35 }
36 void Tarjan(int u)
37 {
38     fa[u]=u;
39     vis[u]=true;
40     for(int i=heade[u];i;i=e[i].next)
41     {
42         int v=e[i].v;
43         if(!vis[v])
44         {
45             dis[v]=dis[u]+e[i].val;
46             Tarjan(v);
47             fa[v]=u;
48         }
49     }
50     for(int i=headq[u];i;i=q[i].next)
51     {
52         int v=q[i].u==u?q[i].v:q[i].u;
53         if(vis[v])lca[i>>1]=getfa(fa[v]);
54     }
55 }
56 int main()
57 {
58     scanf("%d",&n);
59     int x,y,z;
60     for(int i=1;i<n;i++)
61     {
62         scanf("%d%d%d",&x,&y,&z);
63         ++x;++y;
64         adde(x,y,z);
65         adde(y,x,z);
66     }
67     cnt=1;
68     scanf("%d",&Q);
69     for(int i=1;i<=Q;i++)
70     {
71         scanf("%d%d",&x,&y);
72         ++x;++y;
73         addq(x,y);
74         addq(y,x);
75     }
76     Tarjan(1);
77     for(int i=1;i<=Q;i++)
78     {
79         printf("%d\n",getdis(i));
80     }
81     return 0;
82 }

树上倍增

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct edge
 5 {
 6     int v,next,val;
 7 }e[100005];
 8 int n,m,heads[50005],q[50005],head,tail,fa[17][50005],dis[50005],dep[50005],cnt;
 9 void add(int u,int v,int val)
10 {
11     e[++cnt].next=heads[u];
12     heads[u]=cnt;
13     e[cnt].v=v;
14     e[cnt].val=val;
15 }
16 int dfs(int u)
17 {
18     for(int i=heads[u];i;i=e[i].next)
19     {
20         if(e[i].v!=fa[0][u])
21         {
22             dep[e[i].v]=dep[u]+1;
23             fa[0][e[i].v]=u;
24             dis[e[i].v]=dis[u]+e[i].val;
25             dfs(e[i].v);
26         }
27     }
28 }
29 int LCA(int u,int v)
30 {
31     if(dep[u]>dep[v])swap(u,v);
32     for(int i=16;~i;i--)
33         if(dep[fa[i][v]]>=dep[u])
34             v=fa[i][v];
35     if(u==v)return u;
36     for(int i=16;~i;i--)
37         if(fa[i][u]!=fa[i][v])
38         {
39             u=fa[i][u];
40             v=fa[i][v];
41         }
42     return fa[0][u];
43 }
44 int main()
45 {
46     scanf("%d",&n);
47     for(int i=1;i<n;i++)
48     {
49         int x,y,z;
50         x++;y++;
51         scanf("%d%d%d",&x,&y,&z);
52         add(x,y,z);
53         add(y,x,z);
54     }
55     dep[1]=fa[0][1]=1;
56     dfs(1);
57     for(int i=1;i<=16;i++)
58         for(int j=1;j<=n;j++)
59             fa[i][j]=fa[i-1][fa[i-1][j]];
60     scanf("%d",&m);
61     while(m--)
62     {
63         int x,y;
64         x++;y++;
65         scanf("%d%d",&x,&y);
66         printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]);
67     }
68     return 0;
69 }

 

posted @ 2016-10-17 17:28  xqmmcqs  阅读(166)  评论(0编辑  收藏  举报