zoukankan      html  css  js  c++  java
  • 【 Codeforces Round #425 (Div. 2) D】Misha, Grisha and Underground

    Link:http://codeforces.com/contest/832/problem/D

    Description

    给你一棵树;
    然后给你3个点
    让你把这3个点和点s,t,f对应;
    然后s先从s走到f;
    之后t再从t走到f;
    求这两条路径的公共路径的长度;

    Solution

    答案为
    dis(s,f)+dis(t,f)dis(s,t)2
    树上最短路径做一下就好;
    LCA!

    NumberOf WA

    0

    Reviw

    想得太慢了

    Code

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int MAXN = 100000+5;
    const int MAX = 17;
    
    vector <int> son[MAXN],w[MAXN];
    int n,p[MAXN][MAX+5],dep[MAXN],pre[MAX+5],m,t[3];
    long long dis[MAXN];
    
    void input(int &r)
    {
        char t = getchar();
        while (!isdigit(t)) t = getchar();
        r = 0;
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    }
    
    void dfs(int x,int f)
    {
        dep[x] = dep[f] + 1;
        p[x][0] = f;
        for (int i = 1; i <= MAX; i++)
            p[x][i] = p[p[x][i - 1]][i - 1];
        int len = son[x].size();
        for (int i = 0; i <= len - 1; i++)
        {
            int y = son[x][i];
            if (y != f)
            {
                dis[y] = dis[x] + w[x][i];
                dfs(y, x);
            }
        }
    }
    
    int midis(int t0,int t1){
        int pret0,pret1;
        pret0 = t0; pret1 = t1;
        if (dep[t0] > dep[t1])
            swap(t0, t1);
        for (int i = MAX; i >= 0; i--)
            if (dep[t0] <= dep[t1] - pre[i])
                t1 = p[t1][i];
        if (t1 == t0)
        {
            return dis[pret0]+dis[pret1]-2*dis[t0];
        }
        for (int i = MAX; i >= 0; i--)
        {
            if (p[t0][i] == p[t1][i])
                continue;
            t0 = p[t0][i], t1 = p[t1][i];
        }
        return dis[pret0]+dis[pret1]-2*dis[p[t0][0]];
    }
    
    int get_ans(){
        int temp1 = 0;
        for (int S = 0;S <= 2;S++)
            for (int T = 0;T <= 2;T++)
                if (S!=T)
                    for (int F = 0;F <= 2;F++)
                        if (S!=F && T!=F){
                            int temp = midis(t[S],t[F]);
                            temp+=midis(t[T],t[F]);
                            temp-=midis(t[S],t[T]);
                            temp/=2;
                            temp1 = max(temp1,temp);
                        }
        return temp1;
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        pre[0] = 1;
        for (int i = 1; i <= MAX; i++)
            pre[i] = pre[i - 1] << 1;
        input(n); input(m);
        for (int i = 2; i <= n; i++)
        {
            int x;
            input(x);
            son[x].push_back(i);
            w[x].push_back(1);
        }
        dis[1] = 0;
        dfs(1, 0);
        for (int i = 1; i <= m; i++)
        {
            int t0, t1,t2,pret0,pret1;
            for (int j = 0;j <= 2;j++)
                input(t[j]);
            printf("%d
    ",get_ans()+1);
        }
        return 0;
    }
  • 相关阅读:
    mysql分区
    pl/sql查看tnsnames.ora文件路径
    mysql之事务控制和锁定语句
    mysql返回查询行数fund_rows()
    mysql之视图
    Mysql之btree索引和hash索引的区别
    Java中反射 API 的使用
    zookeeper 客户端 Apache curator 分布式锁实操
    springBoot 整合 ZooKeeper Java客户端之 Apache Curator 实战
    初识 ZooKeeper
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626167.html
Copyright © 2011-2022 走看看