bzoj 1832: [AHOI2008]聚会

良心题2333

三个点两两求一遍就行,最小肯定是在某2个点的lca处,(肯定让第三个人去找2个人,不能让2个人一起去找第三个人233)

 1 #include<bits/stdc++.h>
 2 #define N 500005
 3 #define M 10000005
 4 #define LL long long
 5 #define inf 0x3f3f3f3f
 6 using namespace std;
 7 inline int ra()
 8 {
 9     int x=0,f=1; char ch=getchar();
10     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
11     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
12     return x*f;
13 }
14 struct node{
15     int to,next;
16 }e[N<<1];
17 int head[N],cnt;
18 int fa[N][20],deep[N],n,m;
19 void insert(int x, int y){e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;}
20 void dfs(int x)
21 {
22     for (int i=1; i<=19; i++)
23         if (deep[x]>=(1<<i))
24             fa[x][i]=fa[fa[x][i-1]][i-1];
25         else break;
26     for (int i=head[x];i;i=e[i].next)
27     {
28         if (e[i].to==fa[x][0]) continue;
29         fa[e[i].to][0]=x;
30         deep[e[i].to]=deep[x]+1;
31         dfs(e[i].to);
32     }
33 }
34 int lca(int x, int y)
35 {
36     if (deep[x]<deep[y]) swap(x,y);
37     int t=deep[x]-deep[y];
38     for (int i=0; (1<<i)<=t ; i++)
39         if (t&(1<<i)) x=fa[x][i];
40     for (int i=19; i>=0; i--)
41         if (fa[x][i]!=fa[y][i])
42             x=fa[x][i],y=fa[y][i];
43     if (x==y) return x;
44     return fa[x][0];  
45 }
46 int lca_cost(int x, int y)
47 {
48     int sum=0;
49     if (deep[x]<deep[y]) swap(x,y);
50     int t=deep[x]-deep[y];
51     for (int i=0; (1<<i)<=t ; i++)
52         if (t&(1<<i)) x=fa[x][i],sum+=(1<<i);
53     for (int i=19; i>=0; i--)
54         if (fa[x][i]!=fa[y][i])
55             x=fa[x][i],y=fa[y][i],sum+=(1<<i)*2;
56     if (x==y) return sum;
57     return sum+2;  
58 }
59 int main()
60 {
61     n=ra(); m=ra();
62     for (int i=1; i<n; i++)
63     {
64         int x=ra(),y=ra();
65         insert(x,y); insert(y,x);
66     }
67     dfs(1);
68     for (int i=1; i<=m; i++)
69     {
70         int x=ra(),y=ra(),z=ra();
71         int ans1=lca_cost(x,y)+lca_cost(lca(x,y),z);
72         int ans2=lca_cost(x,z)+lca_cost(lca(x,z),y);
73         int ans3=lca_cost(y,z)+lca_cost(lca(y,z),x);
74         int ans=min(min(ans1,ans2),ans3);
75         if (ans==ans1) printf("%d ",lca(x,y));
76         else if (ans==ans2) printf("%d ",lca(x,z));
77         else if (ans==ans3) printf("%d ",lca(y,z));
78         printf("%d\n",ans);
79     }
80 }

 

posted @ 2017-02-23 20:26  ws_ccd  阅读(52)  评论(0编辑  收藏