mc

2 条评论

  • @ 2025-3-30 14:06:57
    //蒟蒻
    //#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;
    }
    
    • @ 2025-3-30 13:20:18

      你进我的世界

      • 1