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;
    }
    
  • 相关阅读:
    DP_knapsack
    也谈交换两个变量
    SidebySide Assembly
    Generate permutation for N elements
    Pixel Shader 像素着色
    Drill into View Matrix
    使用D3DXCreateSphere绘图的步骤
    原来VisualStudio本身也可以查看调试信息
    DirectX Effects初探
    Shortcuts
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6628771.html
Copyright © 2011-2022 走看看