Parent and son

Give you a tree with N vertices and N‐ 1 edges, and then ask you Q queries on “which vertex is Y's son that has the smallest number and which vertex is Y’s descendants that has the smallest number if we choose X as the root of the entire tree?”

InputThe first line of input is an integer T (T<=10) means the case number. 
The first line of each test case contains N(2 ≤ N ≤ 100,000) and Q(1 ≤ Q ≤ 100,000). 
Each of the following N ‐ 1 lines of the test case contains two integers a(1 ≤ a ≤ N) and b(1 ≤ b ≤ N) indicating an edge between a and b. 
Each of the following Q lines of the test case contains two integers X(1 ≤ X ≤ N) and Y(1 ≤ Y ≤ N, Y ≠ X) indicating an query. 
OutputFor each query, output the Y's son which has the smallest number and Y's descendant that has the smallest number if X is the root of the entire tree. If Y has no sons then output “no answers!”. There is an empty line after each case.Sample Input

1
7 3
1 2
1 5
2 3
2 4
5 6
5 7
1 2
5 3
3 2

Sample Output

3 3
no answers!
1 1


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<memory>
#include<bitset>
#include<string>
#include<functional>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

#define MAXN 100006
#define INF 0x3f3f3f3f

struct edge
{
    int to, next;
}E[MAXN*2];
int tot, sz, head[MAXN], L[MAXN], R[MAXN], s[MAXN], fa[MAXN];
void init()
{
    tot = 0;
    sz = 0;
    memset(head, -1, sizeof(head));
    memset(s, 0, sizeof(s));
}
void addedge(int f, int t)
{
    E[tot].to = t;
    E[tot].next = head[f];
    head[f] = tot++;
}
struct node
{
    int min1, min2, id1, id2;
}sn[MAXN],st[MAXN];

void getmin(node& tmp, int num, int v)
{
    if (tmp.min1 > num)
    {
        tmp.min2 = tmp.min1, tmp.id2 = tmp.id1;
        tmp.min1 = num, tmp.id1 = v;
    }
    else if (tmp.min2 > num)
    {
        tmp.min2 = num, tmp.id2 = v;
    }
}

void dfs(int u, int pre)
{
    L[u] = ++sz;
    sn[u].min1 = sn[u].min2 = st[u].min1 = st[u].min2 = INF;
    for (int i = head[u]; i != -1; i = E[i].next)
    {
        int v = E[i].to;
        if (v == pre) continue;
        dfs(v, u);
        fa[v] = u;
        getmin(sn[u], v, v);
        getmin(st[u], min(st[v].min1, v), v);
    }
    R[u] = sz;
}
int main()
{
    int T, n, u, v, q, X, Y;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d%d", &n, &q);
        init();
        for (int i = 0; i < n - 1; i++)
        {
            scanf("%d%d", &u, &v);
            s[u]++;
            s[v]++;
            addedge(u, v);
            addedge(v, u);
        }
        sz = 0;
        fa[1] = INF;
        dfs(1, 0);
        while (q--)
        {
            scanf("%d%d", &X, &Y);
            if (s[Y] == 1)
                printf("no answers!\n");
            else if (L[X]<L[Y] || R[X]>R[Y])
                printf("%d %d\n", sn[Y].min1, st[Y].min1);
            else
            {
                int ans = 1;
                if (Y == 1)
                {
                    if (L[st[Y].id1] <= L[X] && R[st[Y].id1] >= R[X])
                    {
                        ans = st[Y].min2;
                    }
                    else
                        ans = st[Y].min1;
                }
                if (L[sn[Y].id1] <= L[X] && R[sn[Y].id1] >= R[X])
                {
                    printf("%d %d\n", min(fa[Y], sn[Y].min2), ans);
                }
                else
                    printf("%d %d\n", min(fa[Y], sn[Y].min1), ans);
            }
        }
        printf("\n");
    }
}

 

posted @ 2017-08-16 19:00  joeylee97  阅读(262)  评论(0编辑  收藏  举报