P3398 仓鼠找sugar

仓鼠找sugar

洛谷链接

一道提高+/省选-的题目,终于可以提高博客题目的平均难度了。。。

大致题意就是在一棵树上有两条路径,询问这两个路径是不是可以相交。

而如果两条路径相交的话,一定有一条路径a两端点的LCA在另一条的路径上,我们可以通过求路径a的LCA是不是在路径b上来求出a与b是不是相交的。

根据以上推断,可以保证了路径a的LCA的深度一定大于路径b的LCA的深度。只要再在确定路径a的LCA与路径b的两端点其中一点的LCA是路径a的LCA就确保路径a的LCA在路径b上了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #define N 100010
 4 #define M 200010
 5 using namespace std;
 6 int next[M],to[M],num,head[N],size[N],father[N],deep[N],top[N],n,m,a,b,c,d,lca_a_b,lca_c_d;
 7 void add(int false_from,int false_to){
 8     next[++num]=head[false_from];
 9     to[num]=false_to;
10     head[false_from]=num;
11 }
12 void dfs1(int x){
13     size[x]=1;
14     deep[x]=deep[father[x]]+1;
15     for(int i=head[x];i;i=next[i])
16         if(father[x]!=to[i]){
17             father[to[i]]=x;
18             dfs1(to[i]);
19             size[x]+=size[to[i]];
20         }
21 }
22 void dfs2(int x){
23     int mmax=0;
24     if(!top[x])
25         top[x]=x;
26     for(int i=head[x];i;i=next[i])
27         if(father[x]!=to[i]&&size[to[i]]>size[mmax])
28             mmax=to[i];
29     if(mmax){
30         top[mmax]=top[x];
31         dfs2(mmax);
32     }
33     for(int i=head[x];i;i=next[i])
34         if(father[x]!=to[i]&&to[i]!=mmax)
35             dfs2(to[i]);
36 }
37 int lca(int x,int y){
38     while(top[x]!=top[y]){
39         if(deep[top[x]]<deep[top[y]])
40             swap(x,y);
41         x=father[top[x]];
42     }
43     if(deep[x]<deep[y])return x;
44     return y;
45 }
46 int main(){
47     scanf("%d%d",&n,&m);
48     for(int i=1;i<n;++i){
49         scanf("%d%d",&a,&b);
50         add(a,b);
51         add(b,a);
52     }
53     dfs1(1);
54     dfs2(1);
55     for(int i=1;i<=m;++i){
56         scanf("%d%d%d%d",&a,&b,&c,&d);
57         lca_a_b=lca(a,b);
58         lca_c_d=lca(c,d);
59         if(deep[lca_a_b]==deep[lca_c_d]){
60             if(lca_a_b==lca_c_d){
61                 printf("Y\n");
62                 continue;
63             }
64             printf("N\n");
65             continue;
66         }
67         if(deep[lca_a_b]<deep[lca_c_d]){
68             if(lca(lca_c_d,a)==lca_c_d||lca(lca_c_d,b)==lca_c_d)
69                 printf("Y\n");
70             else
71                 printf("N\n");
72         }
73         if(deep[lca_a_b]>deep[lca_c_d]){
74             if(lca(lca_a_b,c)==lca_a_b||lca(lca_a_b,d)==lca_a_b)
75                 printf("Y\n");
76             else
77                 printf("N\n");
78         }
79     }
80     return 0;
81 }
View Code

 

posted @ 2017-05-06 16:07  江屿  阅读(314)  评论(0编辑  收藏  举报