• 【LCA倍增】POJ1330-Nearest Common Ancestors


    【知识点:离线算法&在线算法】

    一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果。

    一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始时并不需要已经知道所有的输入。

    【倍增-在线算法】

    水题……这道题范围卡得很紧…数组少了一位就会WA。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 using namespace std;
      7 const int MAXN=10000+10;
      8 const int DEG=20;
      9 vector<int> E[MAXN];
     10 int n;
     11 int anc[MAXN][DEG],dep[MAXN];
     12 
     13 void addedge(int u,int v)
     14 {
     15     E[u].push_back(v);
     16 }
     17 
     18 void dfs(int v,int p,int d)
     19 {
     20     anc[v][0]=p;
     21     dep[v]=d;
     22     for (int i=0;i<E[v].size();i++)
     23         dfs(E[v][i],v,d+1);
     24 }
     25 
     26 void getanc()
     27 {
     28     for (int i=1;i<DEG;i++)
     29         for (int j=1;j<=n;j++)
     30         {
     31             anc[j][i]=anc[anc[j][i-1]][i-1];
     32         }
     33 }
     34 
     35 int swim(int x,int H)
     36 {
     37     for (int i=0;H>0;i++)
     38     {
     39         if (H&1) x=anc[x][i];
     40         H/=2;
     41     }
     42     return x;
     43 }
     44 
     45 int LCA(int u,int v)
     46 {
     47     if (dep[u]<dep[v]) swap(u,v);
     48     u=swim(u,dep[u]-dep[v]);
     49     if (u==v) return u;
     50     for (int i=DEG-1;i>=0;i--)
     51     {
     52         if (anc[u][i]!=anc[v][i])
     53         {
     54             u=anc[u][i];
     55             v=anc[v][i];
     56         }
     57     }
     58     return anc[u][0];
     59 }
     60 
     61 void init()
     62 {
     63     for (int i=0;i<MAXN;i++) vector<int>().swap(E[i]);
     64     scanf("%d",&n);
     65     int notrt[MAXN];
     66     memset(notrt,0,sizeof(notrt));
     67     for (int i=0;i<n-1;i++)
     68     {
     69         int u,v;
     70         scanf("%d%d",&u,&v);
     71         addedge(u,v);
     72         notrt[v]=1;
     73     }
     74     int rt;
     75     for (int i=1;i<=n;i++) if (!notrt[i])    //这里注意下标是从1开始的
     76     {
     77         rt=i;
     78         break;
     79     }
     80     dfs(rt,0,0);
     81     getanc();
     82 }
     83 
     84 void query()
     85 {
     86     int u,v;
     87     scanf("%d%d",&u,&v);
     88     cout<<LCA(u,v)<<endl;
     89 }
     90 
     91 int main()
     92 {
     93     int T;
     94     scanf("%d",&T);
     95     for (int kase=0;kase<T;kase++)
     96     {
     97         init();
     98         query();
     99     }
    100     return 0;
    101 }

     【待更新】

  • 相关阅读:
    多个文件目录下Makefile的写法
    通用多目录makefile的写法
    一个简单的通用Makefile实现
    Eclipse + CDT + YAGARTO + J-Link,STM32开源开发环境搭建与调试
    Eclipse-cdt 配合 gdbserver 进行 arm 程序远程调试 上
    Eclipse-cdt 配合 gdbserver 进行 arm 程序远程调试 下
    WiEngine+Eclipse+CDT+Sequoyah实现c++编程智能感知提示
    Docker 常用命令总结
    很好用的取代 PuTTY 的SSH远程登陆软件 Termius
    [转]如何优雅地进行参数校验?有什么提高代码稳壮性的方式?
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5384806.html
Copyright © 2020-2023  润新知