E. Xenia and Tree+树上暴力

E. Xenia and Tree
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Xenia the programmer has a tree consisting of n nodes. We will consider the tree nodes indexed from 1 to n. We will also consider the first node to be initially painted red, and the other nodes — to be painted blue.

The distance between two tree nodes v and u is the number of edges in the shortest path between v and u.

Xenia needs to learn how to quickly execute queries of two types:

  1. paint a specified blue node in red;
  2. calculate which red node is the closest to the given one and print the shortest distance to the closest red node.

Your task is to write a program which will execute the described queries.

Input

The first line contains two integers n and m (2 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of nodes in the tree and the number of queries. Next n - 1 lines contain the tree edges, the i-th line contains a pair of integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi) — an edge of the tree.

Next m lines contain queries. Each query is specified as a pair of integers ti, vi (1 ≤ ti ≤ 2, 1 ≤ vi ≤ n). If ti = 1, then as a reply to the query we need to paint a blue node vi in red. If ti = 2, then we should reply to the query by printing the shortest distance from some red node to node vi.

It is guaranteed that the given graph is a tree and that all queries are correct.

Output

For each second type query print the reply in a single line.

Examples
Input
Copy
5 4
1 2
2 3
2 4
4 5
2 1
2 5
1 2
2 5
Output
Copy
0
3
2

#define happy

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define all(a) (a).begin(),(a).end()
#define pll pair<ll,ll>
#define vi vector<int>
#define pb push_back
const int inf=0x3f3f3f3f;
ll rd(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int N=1e5+10;
int dis[N],head[N],nxt[N<<1],v[N<<1],qhead,qtail,q[N];
bool red[N];

void bfs(int s){
    qhead=0;qtail=1;
    q[1]=s;
    dis[s]=0;
    while(qhead<qtail){
        int i=q[++qhead];
        for(int j=head[i];~j;j=nxt[j]){
            int u=v[j];
            if(dis[u]>dis[i]+1){
                dis[u]=dis[i]+1;
                q[++qtail]=u;
            }
        }
    }
}

int vc[N];
int rdis[N];

int rbfs(int s,int st){
    if(red[s])return 0;
    qhead=0;qtail=1;
    q[1]=s;
    vc[s]=st;
    rdis[s]=0;
    while(qhead<qtail){
        int i=q[++qhead];
        for(int j=head[i];~j;j=nxt[j]){
            int u=v[j];
            if(vc[u]!=st){
                vc[u]=st;
                rdis[u]=rdis[i]+1;
                if(red[u]){
                    return rdis[u];
                }
                q[++qtail]=u;
            }
        }
    }
}


int main(){
#ifdef happy
    freopen("in.txt","r",stdin);
#endif
    int top=0;
    memset(head,-1,sizeof(head));
    memset(vc,-1,sizeof(vc));
    int n=rd(),m=rd();
    rep(i,1,n-1){
        int x=rd()-1,y=rd()-1;
        v[top]=y,nxt[top]=head[x],head[x]=top;++top;
        v[top]=x,nxt[top]=head[y],head[y]=top;++top;
    }
    rep(i,0,n-1)dis[i]=inf;
    red[0]=1;
    bfs(0);
    int cnt=1;
    rep(i,0,m-1){
        int x=rd(),y=rd()-1;
        if(x==1){
            red[y]=1;
            ++cnt;
            if(cnt<=300){
                bfs(y);
            }
        }else{
            if(cnt<=300)printf("%d\n",dis[y]);
            else printf("%d\n",rbfs(y,i));
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值