鱼C论坛

 找回密码
 立即注册
查看: 2558|回复: 2

最近公共祖先

[复制链接]
发表于 2022-7-14 10:23:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 柿子饼同学 于 2022-7-14 13:50 编辑

代码不知道问题出在哪 , 总是输出 0
求指出

题目:https://www.luogu.com.cn/problem/P3379
  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. const int N = 5e5 + 10;
  4. //   ST表    深度数组 log2(n)存储
  5. int dp[N][21], dep[N], lg[N];
  6. int n, m, s;
  7. vector<int> tree[N]; // 邻接表存储

  8. void dfs(int x, int p){//x当前节点 , p是x的父母
  9.     dep[x] = dep[p] + 1;
  10.     dp[x][0] = p;
  11.     for(int i = 1; (1<<i)<= dep[x]; i++){
  12.         dp[x][i] = dp[dp[x][i-1]][i-1];
  13.     }
  14.     for(auto i : tree[x]){
  15.         if(i != p) dfs(i, x);
  16.     }
  17. }

  18. int lca(int x, int y){
  19.     if(dep[x] < dep[y]) swap(x, y);
  20.     for(int i = lg[dep[x]]; i >= 0; i--){
  21.         if((1<<i)+dep[x] >= dep[y]){
  22.             x = dp[x][i];
  23.         }
  24.     }
  25.     if(x == y) return y;
  26.     for(int i = lg[dep[x]]; i >= 0; i--){
  27.         if(dp[x][i] != dp[y][i]){
  28.             x = dp[x][i];
  29.             y = dp[y][i];
  30.         }
  31.     }
  32.     return dp[x][0];
  33. }

  34. int main(){
  35.     ios::sync_with_stdio(0);
  36.     cin.tie(0); cout.tie(0);
  37.    
  38.     int x, y;
  39.     cin >> n >> m >> s;
  40.     for(int i = 1; i <= n; i++){//预处理log2(n)
  41.         lg[i] = lg[i-1] + ((1<<lg[i-1])==i);
  42.     }
  43.     for(int i = 1; i < n; i++){
  44.         cin >> x >> y;
  45.         tree[x].push_back(y);
  46.         tree[y].push_back(x);
  47.     }
  48.     dfs(s, s);

  49.     while(m--){
  50.         cin >> x >> y;
  51.         cout << lca(x, y) << endl;
  52.     }

  53.     return 0;
  54. }
复制代码

谢谢大家了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-7-14 18:14:45 | 显示全部楼层
本帖最后由 jhq999 于 2022-7-14 18:30 编辑

看看,没看明白
只能自己写一个还没通过
  1. void huisu(int* a,int n,int pt1,int pt2)
  2. {
  3.     if(pt1==a[0]||pt2==a[0])printf("%d\n",a[0]);
  4.     else
  5.     {
  6.         int i=0,j=0,pt3=pt1,pt4=pt2;
  7.         while(pt3!=a[0])pt3=a[pt3],i++;//////计算到根节点的深度
  8.         while(pt4!=a[0])pt4=a[pt4],j++;//////计算到根节点的深度
  9.         pt3=pt1,pt4=pt2;
  10.         while(1)////////跑到相同的深度
  11.         {
  12.             if(i==j)break;
  13.             i>j?(pt3=a[pt3],i--):(pt4=a[pt4],j--);
  14.         }
  15.         while(pt3!=pt4)////////假如相同深度的值相同就是共同祖先
  16.         {
  17.             pt3=a[pt3],pt4=a[pt4];
  18.         }
  19.         printf("%d\n",pt3);
  20.     }

  21. }
  22. int main()
  23. {

  24.     int n=0,m=0,s=0,i=0,id=0,parent=0;
  25.     scanf("%d%d%d",&n,&m,&s);
  26.     int* a=(int*)calloc(n+1,sizeof(int));
  27.     int (*b)[2]=(int (*)[2])calloc(m*2,sizeof(int));
  28.     a[0]=s;
  29.     for(i=0;i<n-1;i++)
  30.     {
  31.         scanf("%d%d",&id,&parent);
  32.         a[id]=parent;/////每个节点存储的是父节点下标
  33.     }
  34.     for(i=0;i<m;i++)
  35.     {
  36.         scanf("%d%d",b[i],b[i]+1);
  37.     }
  38.     for(i=0;i<m;i++)
  39.     {

  40.         huisu(a,n,b[i][0],b[i][1]);
  41.     }
  42.     free(b);
  43.     free(a);

  44.     return 0;
  45. }
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-15 09:25:48 | 显示全部楼层
jhq999 发表于 2022-7-14 18:14
看看,没看明白
只能自己写一个还没通过

唔 , 这个可能没有用 ST 表那么快
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-3 12:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表