zoukankan      html  css  js  c++  java
  • 2017广东工业大学程序设计竞赛决赛 F(LCA + 斐波那契数列性质)

    不能组成三角形的极端数列:1,1,2,3,5,8,13,21,……到第50项时候肯定到1e9了……

    如果两个点之间距离大于50,则直接Yes……

    否则的话直接暴力取出所有边,然后升序排序,判断一下就可以了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b) for (int i(a); i <= (b); ++i)
    #define dec(i, a, b) for (int i(a); i >= (b); --i)
    
    const int N = 100010;
    const int A = 26;
    
    vector <pair <int, int> > v[N];
    int f[N][A], deep[N], b[N], c[A << 1];
    int n, x, y, z, q;
    int T, cnt = 0;
    
    void dfs(int x, int fa, int dep){
        deep[x] = dep;
        if (fa){
          f[x][0] = fa;
          for (int i = 0; f[f[x][i]][i]; ++i) f[x][i + 1] = f[f[x][i]][i];
        }
    
        for (auto cnt : v[x]){
          if (cnt.first == fa) continue;
          b[cnt.first] = cnt.second;
          dfs(cnt.first, x, dep + 1);
        }
    
    }
    
    int LCA(int a, int b){
        if (deep[a] < deep[b]) swap(a, b);
        for (int i = 0,  delta = deep[a] - deep[b]; delta; delta >>= 1, ++i)
            if (delta & 1) a = f[a][i];
    
        if (a == b) return a;
        dec(i, 19, 0) if (f[a][i] != f[b][i]){
            a = f[a][i];
            b = f[b][i];
        }
    
        return f[a][0];
    }
    
    void Solve(int x, int y){
        if (deep[x] < deep[y]) swap(x, y);
        for (; deep[x] > deep[y]; ){
          c[++cnt] = b[x];
          x = f[x][0];
        }
    
        for (; x != y; ){
          c[++cnt] = b[x];
          c[++cnt] = b[y];
          x = f[x][0], y = f[y][0];
        }
    }
    
    int main(){
        
        for (scanf("%d", &T); T--; ){
           scanf("%d", &n);
           memset(deep, 0, sizeof deep);
           rep(i, 0, n) v[i].clear();
           memset(f, 0, sizeof f);
    
            rep(i, 1, n - 1){
             scanf("%d%d%d", &x, &y, &z);
              v[x].push_back({y, z});
              v[y].push_back({x, z});
            }
    
            dfs(1, 0, 1);
          for(scanf("%d", &q); q--;){
              scanf("%d%d", &x, &y);
              int lca = LCA(x, y), dis = deep[x] + deep[y] - deep[lca] * 2;
              if (dis > 50) {puts("Yes"); continue;}
              memset(c, 0, sizeof c); cnt = 0;
              Solve(x, y); sort(c + 1, c + cnt + 1);
              bool fl = false;
              rep(i, 1, cnt - 2) if (c[i] + c[i + 1] > c[i + 2]){
                fl = true;
                break;
              }
              puts(fl ? "Yes" : "No");
    
           }
        }
    
        return 0;
    }
    
  • 相关阅读:
    从零开始学 Web 之 Vue.js(一)Vue.js概述,基本结构,指令,事件修饰符,样式
    从零开始学 Web 之 Vue.js(二)过滤器,按键修饰符,自定义指令
    js获取某个时间段前多长时间
    Object.create()详解
    React Redux
    react 路由按需加载
    react @types/react-router-dom报错
    create-react-app 创建react ts项目启动报错
    十进制转二进制、八进制、十六进制(js)
    代码编辑器设置自定义提示
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6628771.html
Copyright © 2011-2022 走看看