Beijing Normal University Fifteenth ACM Finals - Race reproduce B Borrow Classroom (tree --LCA)

Links: https://ac.nowcoder.com/acm/contest/3/B
Source: Cattle-off network

Borrow Classroom
Time limit: C / C ++ 3 seconds to 6 seconds languages other
space restrictions: C / C ++ 262144K, other languages 524288K
64bit IO the Format:% LLD
topic describes
the annual BNU school race will have two training before the game, for which it need to borrow the classroom, the students are busy due SK topic, this thing came from small errands Q classmates. SK students ready to go from the hostel, to borrow the classroom to the list of small Q students let him take Dean stamp, but what the teacher suddenly found SK students seem to take the wrong classroom, wanted to rob the list was sent to the Senate in borrowed classrooms intercept them before at.

Now the campus abstracted into a tree of n nodes, the length of each side is a unit length, numbered from 1 to n, wherein a node located Dean, q has a next interrogation, interrogation SK students each will be starting from the node B, to C node number found on small Q students and classrooms to him by the list, and then again a small Q students from node C of departure to the Registry, where the teacher will depart from node a to start interception.

Everyone walking in a unit of time up to a unit of distance, as long as the teacher he encountered took the list before the list has not been sent to the Office of Academic Affairs students are considered successful interception, if small Q students have to Dean, then because of the small Q classmates fast hand speed, the list will be pay up immediately, even if what the teacher to the Dean does not help, you need to determine whether any teacher can be successful interception.
Input Description:
The first line is a positive integer T (≤ 5), represents the number of test cases for each set of test data, a first line of two integers n, q (1≤ n, q ≤ 100000), respectively, represents the number of nodes and interrogation, the next n-1 rows, each row comprising two integers x, y (1≤ x, y ≤ n), expressed an edge connected between x and y, to ensure that these sides can form a tree, then q rows, each row containing three integers a, B, C (1 ≤ a, B, C ≤ n), represents a query, where a is the location where the teacher, B is a position where SK students, C is a position where the small Q students to ensure that students initially not small Q Academic Affairs.
Output Description:
For each inquiry, output line, if any teacher can successfully intercept the output "YES" (without the quotes), otherwise the output "NO" (without the quotes).
Example 1
Input
Copy
1
. 7 2
1 2
2. 3
. 3. 4
. 4. 7
1. 5
1. 6
. 3. 5. 6
. 7. 5. 6
output
copy
YES
NO

Meaning of the questions: idea: we have to discuss the situation into two categories, A and C common ancestor is not a case of 1 and 1, ① when the node A and node C of LCA is 1, it indicates that, at node A leading 1 path and the path leading to the node C is not the point of intersection, then a must to be successful interception node a distance of 1 to less than B-> C - from> 1 ② LCA is not the time 1, then leading to 1 on the path to a node is an intersection, and the intersection before reaching one, then we need only from node a to less B-> C - distance> 1 can be successfully intercepted.





I seek a two-node distance is doubled with LCA method.

See details Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
std::vector<int> son[maxn];
int depth[maxn];
int far[maxn][22];
int n,q;
void dfs(int x,int pre)
{
//    cout<<x<<" "<<pre<<endl;
    depth[x]=depth[pre]+1;
    far[x][0]=pre;
    for(int i=1;i<20;i++)
    {
        far[x][i]=far[far[x][i-1]][i-1];
    }
//    for(int i=1;i<20;i++)
//    {
//        fa[rt][i]=fa[fa[rt][i-1]][i-1];
//    }
    for(auto y:son[x])
    {
        if(y!=pre)
        {
            dfs(y,x);
        }
    }
}
int lca(int x,int y)
{
    if(depth[x]<depth[y])
    {
        swap(x,y);
    }
    for(int i=19;i>=0;i--)
    {
        if(depth[x]-(1<<i)>=(depth[y]))
        {
            x=far[x][i];
        }
    }
    if(x==y)
    {
        return x;
    }
    for(int i=19;i>=0;i--)
    {
        if(far[x][i]!=far[y][i])
        {
            x=far[x][i];
            y=far[y][i];
        }
    }
    return far[x][0];
}
int getdist(int x,int y)
{
    int z=lca(x,y);
    int res=depth[x]+depth[y]-2*depth[z];
    return res;
}
int main()
{
//    freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    int t;
    gbtb;
    cin>>t;
    while(t--)
    {
        cin>>n>>q;
        int u,v;
        repd(i,1,n)
        {
            son[i].clear();
        }
        repd(i,2,n)
        {
            cin>>u>>v;
            son[v].pb(u);
            son[u].pb(v);
        }
        depth[0]=0;
        dfs(1,0);
        while(q--)
        {
            int a,b,c;
            cin>>a>>b>>c;
            int a1=getdist(a,1);
            int bc=getdist(b,c);
            int c1=getdist(c,1);
            int ac=getdist(a,c);
//          cout<<a1<<" "<<bc<<" "<<c1<<" "<<ac<<endl;
            if(a1<bc+c1)
            {
                cout<<"YES"<<endl;
            }else if(ac<=bc)
            {
                cout<<"YES"<<endl;
            }else if(lca(a,c)!=1&&a1<=bc+c1)
            {
                cout<<"YES"<<endl;
            }else
            {
                cout<<"NO"<<endl;
            }
        }
    }



    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}

Guess you like

Origin www.cnblogs.com/qieqiemin/p/11018522.html