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");
    }
    }
    }

  • 相关阅读:
    检测单链表是否含有环
    巧用正则和document.location.search获取URL参数的值
    网站前端性能优化
    Ubuntu 10.10 wubi安装错误处理
    SQL中随机数函数rand()简介
    C#实现智能提示(提示补全)功能
    重装系统使之svn再次复活
    MongoDB安装
    mongodb查询
    解决iframe中跨域session丢失的问题
  • 原文地址:https://www.cnblogs.com/liyongmou/p/1800188.html
Copyright © 2011-2022 走看看