CODEVS 2370 小机房的树

传送门:Problem 2370

https://www.cnblogs.com/violet-acmer/p/9686774.html

 

AC代码:

Tarjan+LCA:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define pb(x) push_back(x)
 7 const int maxn=5e4+50;
 8 
 9 int n,q;
10 int fa[maxn];
11 int dist[maxn];
12 bool vis[maxn];
13 int res[75050];
14 struct Node
15 {
16     int to;
17     int weight;
18     Node(int to,int weight):to(to),weight(weight){}
19 };
20 vector<Node >edge[maxn],query[maxn];
21 void addEdge(int u,int v,int w)
22 {
23     edge[u].pb(Node(v,w));
24     edge[v].pb(Node(u,w));
25 }
26 void addQuqry(int u,int v,int id)
27 {
28     query[u].pb(Node(v,id));
29     query[v].pb(Node(u,id));
30 }
31 
32 //===========LCA================
33 int Find(int x)
34 {
35     return x == fa[x] ? x:fa[x]=Find(fa[x]);
36 }
37 void Dfs(int v,int f,int l)
38 {
39     fa[v]=v;
40     dist[v]=l;
41     vis[v]=true;
42     for(int i=0;i < edge[v].size();i++)
43     {
44         int to=edge[v][i].to;
45         int w=edge[v][i].weight;
46         if(to != f)
47         {
48             Dfs(to,v,l+w);
49             fa[to]=v;
50         }
51     }
52     for(int i=0;i < query[v].size();i++)
53     {
54         int to=query[v][i].to;
55         int id=query[v][i].weight;
56         if(vis[to])
57             res[id]=dist[to]-dist[Find(to)]+dist[v]-dist[Find(to)];
58     }
59 }
60 void Tarjan()
61 {
62     for(int i=1;i <= n;++i)
63         if(!vis[i])
64             Dfs(i,i,0);
65 }
66 //==============================
67 //==============================
68 void Init()
69 {
70     memset(vis,false,sizeof vis);
71     memset(res,-1,sizeof res);
72     for(int i=1;i <= n;++i)
73         edge[i].clear(),query[i].clear();
74 }
75 int main()
76 {
77     Init();
78     scanf("%d",&n);
79     for(int i=1;i < n;++i)
80     {
81         int u,v,w;
82         scanf("%d%d%d",&u,&v,&w);
83         addEdge(u,v,w);
84     }
85     scanf("%d",&q);
86     for(int i=1;i <= q;++i)
87     {
88         int u,v;
89         scanf("%d%d",&u,&v);
90         addQuqry(u,v,i);
91     }
92     Tarjan();
93     for(int i=1;i <= q;++i)
94         printf("%d\n",res[i]);
95 }
View Code

二分+LCA:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define pb(x) push_back(x)
 7 const int maxn=5e4+50;
 8 
 9 int n,q;
10 int fa[20][maxn];
11 int dist[maxn];
12 int depth[maxn];
13 struct Node
14 {
15     int to;
16     int w;
17     Node(int to,int w):to(to),w(w){}
18 };
19 vector<Node >edge[maxn];
20 void addEdge(int u,int v,int w)
21 {
22     edge[u].pb(Node(v,w));
23     edge[v].pb(Node(u,w));
24 }
25 //==============LCA============
26 void Dfs(int v,int f,int d,int l)
27 {
28     depth[v]=d;
29     dist[v]=l;
30     fa[0][v]=f;
31     for(int i=0;i < edge[v].size();i++)
32     {
33         int to=edge[v][i].to;
34         int w=edge[v][i].w;
35         if(to != f)
36             Dfs(to,v,d+1,l+w);
37     }
38 }
39 int LCA(int u,int v)//it faster than the method in book
40 {
41     if(depth[u] > depth[v])
42         swap(u,v);//guarantee depth[v] > depth[u]
43     int i;
44     for(i=0;(1<<i) <= depth[v];i++);//find the max k that v can <<
45     i--;
46     for(int k=i;k >= 0;--k)
47         if((depth[v]-(1<<k)) >= depth[u])
48            v=fa[k][v];
49     if(v == u)
50         return v;
51     for(int k=i;k >= 0;--k)
52         if(fa[k][v] != -1 && fa[k][v] != fa[k][u])
53         {
54             u=fa[k][u];
55             v=fa[k][v];
56         }
57     return fa[0][v];
58 }
59 void Pretreat()
60 {
61     for(int i=1;i <= n;++i)
62         if(!depth[i])
63             Dfs(i,-1,0,0);
64     for(int k=0;k+1 < 20;k++)
65         for(int v=1;v <= n;++v)
66             if(fa[k][v] == -1)
67                 fa[k+1][v]=-1;
68             else
69                 fa[k+1][v]=fa[k][fa[k][v]];
70 }
71 //=============================
72 void Init()
73 {
74     memset(depth,0,sizeof(depth));
75 }
76 int main()
77 {
78     Init();
79     scanf("%d",&n);
80     for(int i=1;i < n;i++)
81     {
82         int u,v,w;
83         scanf("%d%d%d",&u,&v,&w);
84         addEdge(u,v,w);
85     }
86     Pretreat();
87     scanf("%d",&q);
88     for(int i=1;i <= q;++i)
89     {
90         int u,v;
91         scanf("%d%d",&u,&v);
92         int lca=LCA(u,v);
93         printf("%d\n",dist[u]+dist[v]-2*dist[lca]);
94     }
95 }
View Code

 

posted @ 2018-09-24 09:18  HHHyacinth  阅读(223)  评论(0编辑  收藏  举报