zoukankan      html  css  js  c++  java
  • LCA与RMQ yongmou

    参见topcoder的算法教程,Range Minimum Query and Lowest Common Ancestor

    JOJ 一个题目:

    2408 Beautiful girl, 题意:一颗树,给定三个顶点A、B、C,判断A与B之间的路径是否可以经过C

    代码:

    代码
    /*
    * LCA->RMQ
    */
    #include
    <cstdio>
    #include
    <vector>
    #include
    <cmath>
    using namespace std;
    #define MY_MAX 50010

    vector
    <int> graph[MY_MAX];

    void read(int n){
    int i, u, v;
    for(i=0; i<n; ++i)
    if(!graph[i].empty())
    graph[i].clear();
    for(i=1; i<n; ++i){
    scanf(
    "%d %d", &u, &v);
    graph[u].push_back(v);
    graph[v].push_back(u);
    }
    }

    int E[MY_MAX*2];//E[i] is the label of i-th visited node in the tour
    int L[MY_MAX*2];//L[i] is the level of node E[i]
    int H[MY_MAX]; //the index of the first occurrence of node i in E

    bool visited[MY_MAX];
    void DFS(int u, int d, int &k){
    visited[u]
    = true;
    E[k]
    = u;
    L[k]
    = d;
    H[u]
    = k;
    ++k;
    int v;
    for(size_t i=0; i<graph[u].size(); ++i){
    v
    = graph[u][i];
    if(!visited[v]){
    DFS(v, d
    +1, k);
    E[k]
    = u;
    L[k]
    = d;
    ++k;
    }
    }
    }

    int M[MY_MAX*2][20]; //存储的索引
    void preprocess(int a[], int n){
    int i, j;
    //initialize for the intervals with length 1
    for(i=0; i<n; ++i)
    M[i][
    0] = i;
    //compute values from smaller to bigger intervals
    for(j=1; 1<<j <= n; ++j){
    for(i=0; i + (1<<j) - 1 < n; ++i)
    if(a[M[i][j - 1]] < a[M[i + (1<<(j-1))][j-1]])
    M[i][j]
    = M[i][j-1];
    else
    M[i][j]
    = M[i + (1<<(j-1))][j-1];
    }
    }

    int RMQ(int a[], int i, int j){
    if(i > j)
    swap(i, j);
    int k;
    k
    = int(log(j-i+1) / log(2.0));
    if(a[M[i][k]] < a[M[j - (1<<k) + 1][k]])
    return M[i][k];
    else
    return M[j - (1<<k) + 1][k];
    }

    int main(){
    // freopen("in", "r", stdin);
    int n, m, k, case_num = 1;
    while(scanf("%d", &n) != EOF){
    read(n);
    for(k=0; k<n; ++k)
    visited[k]
    = false;
    k
    = 0;
    DFS(
    0, 0, k);

    preprocess(L,
    2*n-1);

    int a, b, c;
    int lab, lac, lbc;
    if(case_num != 1)
    printf(
    "\n");
    printf(
    "Case %d:\n", case_num++);

    scanf(
    "%d", &m);
    for(k=0; k<m; ++k){
    scanf(
    "%d %d %d", &a, &b, &c);
    lab
    = E[RMQ(L, H[a], H[b])];
    lac
    = E[RMQ(L, H[a], H[c])];
    lbc
    = E[RMQ(L, H[b], H[c])];
    if(a == c || b == c || (lab == lac && lbc == c)
    || (lab == lbc && lac == c))
    printf(
    "Yes\n");
    else
    printf(
    "No\n");
    }
    }
    }

  • 相关阅读:
    PHP 日志专题
    ThinkPHP 3.2 用户注册邮箱验证帐号找回密码
    ThinkPHP 3.2 用户注册邮箱验证激活帐号
    ThinkPHP 3.2 vendor()方法的深入研究及Phpqrcode的正确扩展
    基于Composer的Laravel扩展包开发工作流
    如何利用showdoc自动生成API文档
    PHP中的几个随机数生成函数
    isset在php5.6-和php7.0+的一些差异
    PHP学习方向-进阶2(三)
    Jupyter Notebook 下安装 PHP 内核
  • 原文地址:https://www.cnblogs.com/liyongmou/p/1800188.html
Copyright © 2011-2022 走看看