zoukankan      html  css  js  c++  java
  • 【vijos1460】拉力赛

    描述

    车展结束后,游乐园决定举办一次盛大的山道拉力赛,平平和韵韵自然也要来参加大赛。

    赛场上共有n个连通的计时点,n-1条赛道(构成了一棵树)。每个计时点的高度都不相同(父结点的高度必然大于子结点),相邻计时点间由赛道相连。由于马力不够,所以韵韵的遥控车只能从高处驶向低处。而且韵韵的车跑完每条赛道都需花费一定的时间。

    举办方共拟举办m个赛段的比赛,每次从第u个计时点到第v个计时点,当然其中有不少比赛韵韵的遥控车是不能参加的(因为要上坡)。平平想知道他能参加多少个赛段的比赛,并且想知道他完成这些赛段的总用时。

    赛道皆为单向。

    格式

    输入格式

    第一行两个整数n,m。

    接下来n-1行每行3个整数a、b、t。

    表示韵韵的遥控车可以花t秒从第a个计时点到第b个计时点。

    接下来m行每行2个整数u、v,意义如描述所示。

    输出格式

    第一行输出一个正整数,表示能参加的赛段数。

    第二行输出一个正整数,表示总用时。

    样例1

    样例输入1

    6 2
    1 2 1
    2 4 1
    2 5 1
    5 6 1
    1 3 1
    2 6
    4 5

    样例输出1

    1
    2

    限制

    各个测试点1s

    提示

    第一个计时点的高度是最高的;
    u≠v;
    对于50%的数据 n≤1000 m≤1000;
    对于100%的数据 n≤10000 m≤100000;
    答案小于2^64。

    来源

    f1zsy birdor

    题解

    比LCA还要简单一点。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=10000+5;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int n,m,num,cnt;
    int head[maxn],dep[maxn],f[maxn][20],dis[maxn];
    ll ans;
    struct node
    {
        int next,to,dist;
    }e[maxn];
    void add(int from,int to,int dist)
    {
        e[++num].next=head[from];
        e[num].to=to;
        e[num].dist=dist;
        head[from]=num;
    }
    void dfs(int x,int d)
    {
        dep[x]=d;
        for(int i=head[x];i;i=e[i].next)
        {
            int to=e[i].to;
            f[to][0]=x;
            dis[to]=dis[x]+e[i].dist;
            dfs(to,d+1);
        }
    }
    int lca(int a,int b)
    {
        if(dep[a]>dep[b]) return -1;
        if(dep[a]<dep[b]){int t=a;a=b;b=t;}
        int x=a,y=b;
        int d=dep[x]-dep[y];
        for(int i=0;i<=14;i++)
        if(d&(1<<i)) x=f[x][i];
        if(x==y) return dis[a]-dis[b];
        return -1;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<n;i++)
        {
            int x,y,z;
            x=read();y=read();z=read();
            add(x,y,z);
        }
        dfs(1,1);
        for(int j=1;j<=14;j++)
        for(int i=1;i<=n;i++)
        f[i][j]=f[f[i][j-1]][j-1];
        for(int i=1;i<=m;i++)
        {
            int a,b;
            a=read();b=read();
            int t=lca(a,b);
            if(t!=-1)
            {
                cnt++;
                ans+=t;
            }
        }
        printf("%d
    %lld",cnt,ans);
        return 0;
    }
        
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/bahl/p/7270088.html
Copyright © 2011-2022 走看看