using namespace std;
const int N = 1e4+10;
int n, q, x, y, father[N][25], dep[N];
vector<int>g[N];// 方便深搜遍历
void dfs(int x){
	if(father[x][0] == 0){
		dep[x] = 1;
	}
	else {
		dep[x] = dep[father[x][0]]+1;
	}
	for(int i = 0;i<g[x].size();i++){
		int v = g[x][i];//x 能到达的点
		if(v!= father[x][0]){
			dfs(v);
		}
	}
}
int LCA(int x, int y){
	//调平
	if(dep[x]<dep[y]){//保证x较深 
		swap(x, y);
	}
	int k = 0;
	for(int i = 15;i>=0;i--){
		if(dep[father[x][i]]>=dep[y]){
			x = father[x][i];
		}
	}
	if(x == y) return x;
    //一起往上跳 
    for(int i = 15;i>=0;i--){
		if(father[x][i] != father[y][i]){
			x = father[x][i];
			y = father[y][i];
		}
	}
	return father[x][0];
	
	
}
int main(){
    scanf("%d", &n);
    for(int i = 1;i<n;i++){
		scanf("%d %d", &x, &y);//输入边
		g[x].push_back(y);
		father[y][0] = x;
	}
	//找一下根 
	int root;
	for(int i = 1;i<=n;i++){
		if(father[i] == 0){
			root = i;
			break;
		}
	}
	dfs(root);//统计每个点的深度 
	// 处理st表 
	for(int j = 1;(1<<j)<=n;j++){
		for(int i =1;i<=n;i++){
			father[i][j] = father[father[i][j-1]][j-1];
		}
	} 	
	scanf("%d", &q);
	while(q--){
		scanf("%d %d",&x, &y);
		printf("%d\n", LCA(x, y));
	}
	return 0;
}

1 条评论

  • @ 2025-3-30 14:47:09
    //蒟蒻
    //#pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 10010;
    int n, q, a, b, father[N][25], dep[N];
    vector<int> g[N]; //邻接链表
    
    void dfs (int u) { // 统计深度 
    	if( father [u][0] == 0 ) dep[u] = 1;
    	else dep[u] = dep[father[u][0]] + 1;	
    	for (int i = 0; i < g[u].size(); i++) {
    		int v = g[u][i];
    		if ( v != father[u][0] ) dfs(v); //不走回头路 
    	}
    	
    }
    int LCA(int x, int y){
    	//调平?
      	if(dep[x] < dep[y]) swap(x, y);
    	for(int i = 15; i >= 0; i--){
        	if(dep[father[x][i]] >= dep[y]) x = father[x][i];
    		if(x == y) return x;   
    		// 一起上浮
    		for(int i = 15; i >= 0; i--){
    			if(father[x][i] != father[y][i]){
                	x = father[x][i];
               		y = father[y][i];
            	}
            }
        }  
    	// 再向上一步
       	return father[x][0];
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	
    	scanf ( "%d", &n );
    	for (int i = 1; i < n; i++) {
    		scanf ( "%d %d", &a, &b );
    		g[a].push_back(b);
    		father[b][0] = a;
    	}
    	
    	//找一下根
    	int root; 
    	for(int i = 1; i<= n; i++) {
    		if(father[i][0] == 0) {
    			root = i;
    			break;		
    		}
    	}
    	dfs(root);
    	
    	//处理st表
    	
    	for (int j = 1; (1 << j) <= n; j++) {
    		for (int i = 1; i <= n; i++) { // 枚举起点 
    			father [i][j] = father[father[i][j-1]][j-1];  
    		}
    	} 
    	scanf("%d", &q);
    	while(q--){
            scanf("%d %d", &a, &b);
    		printf("%d\n",LCA(a, b));
        }
    	return 0;
    }
    
    • 1

    信息

    ID
    1376
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    (无)
    递交数
    148
    已通过
    32
    上传者