1. 在此之前我掌握的分块算法仅指 用 Sqrt(n)的时间回答一次询问
2. 这道题和之前做过的一道AC-machine的题目非常像,也是分块做法。一批一批的处理动态更新,询问的结果一般由两部分共同组成。
3. 另外这道题更新的时候显然bfs比dfs更优秀
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <cctype>
#include <cmath>
#include <vector>
#include <sstream>
#include <bitset>
#include <deque>
#include <iomanip>
using namespace std;
#define pr(x) cout << #x << " = " << x << endl;
#define bug cout << "bugbug" << endl;
#define ppr(x, y) printf("(%d, %d)\n", x, y);
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define SQR(a) ((a)*(a))
#define PCUT puts("\n---------------")
typedef long long ll;
typedef double DBL;
typedef pair<int, int> P;
typedef unsigned int uint;
const int MOD = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1e5 + 4;
const int maxm = 1e4 + 4;
const double pi = acos(-1.0);
int u, v, cmd, n, q, st[maxn][20], dp[maxn], depth[maxn];
bool red[maxn];
vector<int> G[maxn];
void init(){
for (int i = 1; i < 20; ++i)
for (int j = 1; j <= n; ++j)
st[j][i] = st[st[j][i-1]][i-1];
}
int LCA(int u, int v){
if (depth[u] > depth[v]) swap(u, v);
int Sub = depth[v] - depth[u];
for (int i = 0; i < 20; ++i)
if (Sub >> i & 1) v = st[v][i];
if (u == v) return Sub;
int up = 0;
for (int i = 19; i > -1; --i)
if (st[u][i] != st[v][i]){
up += 1 << i;
u = st[u][i];
v = st[v][i];
}
return Sub + up * 2 + 2;
}
void DFS(int u, int f, int deep){
st[u][0] = f;
depth[u] = deep;
for (int i = 0; i < G[u].size(); ++i){
int to = G[u][i];
if (to == f) continue;
DFS(to, u, deep+1);
}
return;
}
void dfs1(int u){
if (red[u]) dp[u] = 0;
for (int i = 0; i < G[u].size(); ++i){
int to = G[u][i];
if (to == st[u][0]) continue;
dfs1(to);
dp[u] = min(dp[u], dp[to] + 1);
}
return;
}
void dfs2(int u){
if (u != 1) dp[u] = min(dp[u], dp[st[u][0]] + 1);
for (int i = 0; i < G[u].size(); ++i){
int to = G[u][i];
if (to == st[u][0]) continue;
dfs2(to);
}
return;
}
vector<int> change;
queue<P> Q;
void bfs(){
for (int i = 0; i < change.size(); ++i){
Q.push(P(change[i], 0));
dp[change[i]] = 0;
}
while(Q.size()){
P top = Q.front(); Q.pop();
u = top.first, v = top.second;
for (int i = 0; i < G[u].size(); ++i){
int to = G[u][i];
if (dp[to] > v + 1){
dp[to] = v + 1;
Q.push(P(to, v+1));
}
}
}
return;
}
int main(){
//必须编译过才能交
// ios::sync_with_stdio(false);
int ik, i, j, k, kase;
scanf("%d%d", &n, &q);
memset(dp, 0x3f, sizeof dp);
for (i = 1; i < n; ++i){
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(1, 1, 1);
init();
memset(red, 0, sizeof red);
red[1] = true;
dfs1(1);
dfs2(1);
int bk = sqrt(n);
while(q--){
scanf("%d%d", &cmd, &u);
if (cmd == 1){
change.push_back(u);
red[u] = true;
if (change.size() == bk){
bfs();
change.clear();
}
}else{
int ans = dp[u];
for (i = 0; i < change.size(); ++i)
ans = min(ans, LCA(u, change[i]));
// pr(ans);
printf("%d\n", ans);
}
}
return 0;
}