E 缆车

题目描述:

在远离大陆的太平洋上,有一个风景优美的小岛。传说,小岛上的文明是这样发展起来的。第一代人沿着岛的坡度选择了n 个定居点,编号为1,2,…,n. 其中编号 i 定居点的高度就是i米。他们在定居点的附近修建了房屋,开辟了农田,种植了植物。第二代人在 n 个定居点之间修建了n-1条小路,每条小路连接两个定居点,且任意两个定居点之间都可以通过小路相互到达,互通有无。各个定居点不仅高度不同,而且距离非常远.随着技术的提高,第三代人将盘岛小路改造成可以通缆车的道路。这样不同定居点的人们不费力气就可以借助缆车,自由地到达任何一个定居点。为了纪念开辟文明的先辈,每年,小岛上都会举行一种特殊的仪式。每年的仪式会选择两个定居点x, y,人们将自己的思念和祝愿写成信件放入缆车,缆车将从定居点x 出发,沿着唯一的路径驶向定居点y。为了体会到翻山越岭的感觉, 岛民们希望缆车行车路线满足如下条件:缆车依次经过若干定居点a1, a2,…, ak,岛民们认为,如果存在i,在满足 1<i<k 条件下, a1< a2<……< ai 且 ai >ai+1 ……> aka1可以作为出发点,ak 可以作为终止点。岛民想要知道,存在多少种不同路径的仪式方案? 所谓两个仪式方案不同,是指在满足约束条件下,如果他们的出发节点不同,或者结束点不同。

输入描述:

第一行: T 表示以下有T组测试数据 ( 1≤ T ≤ 5 )
对每组数据,第1行: 一个整数n表示定居点个数。 接下来有n-1行,每行两个整数ai aj,表示定居点ai到定居点aj之间有一条缆车路线。1 ≤ n ≤ 2* 10^5

输出描述:

对每组测试数据,输出一个正整数,表示有多少种不同的仪式方案。

样例输入:

1
4
1 4
2 4
3 4

样例输出:

6

题目解析:

寻找每一个以较大节点的最大值的路径,分为两步dfs就出来了

上代码:

#include<bits/stdc++.h>
using namespace std;
long long n;
vector<long long> a[200005];
long long flag[200005];
long long biao[200005];
long long b[200005];
long long jiang[200005];
long long dfs(long long what)
{
    biao[what]=1;
    if(b[what])return b[what];
    if(flag[what]==0)return b[what]=1;
    b[what]=1;
    for(long long i=0;i<a[what].size();i++)
    {
        long long en=dfs(a[what][i]);
        b[what]+=en;
    }
    return b[what];
}//b表示他的链接的小型子节点中包括自己的子节点个数
long long zhao(long long what)
{
    if(jiang[what])return jiang[what];
    if(flag[what]==0)return jiang[what]=0;
    for(long long i=0;i<a[what].size();i++)
    {
        for(long long j=i+1;j<a[what].size();j++)
        {
            jiang[what]+=b[a[what][i]]*b[a[what][j]];
        }
    }
    return jiang[what];
}//jiang表示以此为最大值的路径个数
int main()
{
    long long t;
    scanf("%lld",&t);
    while(t--)
    {
        for(long long i=0;i<200005;i++)
        {
            a[i].clear();
        }
        memset(flag,0,sizeof(flag));
        memset(b,0,sizeof(b));
        memset(jiang,0,sizeof(jiang));
        memset(biao,0,sizeof(biao));//可能有点蠢的初始化,如果有更好的方法,麻烦留言,会调整
        scanf("%lld",&n);
        long long x,y;
        long long i,j;
        for(i=1;i<n;i++)
        {
            scanf("%lld%lld",&x,&y);
            if(x<y)
            {
                a[y].push_back(x);
                flag[y]++;
            }
            else 
            {
                a[x].push_back(y);
                flag[x]++;
             } 
        }
        long long sum=0;
        for(i=n;i>=1;i--)
        {
            if(biao[i]==0)
            dfs(i);
        }
        for(i=n;i>=1;i--)
        {
            sum+=zhao(i);
        }
        printf("%lld\n",sum*2);//起止点可以互换
    }
    return 0;
 }

如此图片中,9的下一级节点6,b[6]=3,b[7]=2,b[8]=3;
所以,以9位最大节点的路径个数为3乘3+3乘2+3乘2,同理,退出以6,7,8为最大节点的路径个数,相加,最后因为起止点可以互换,所以乘2

在这里插入图片描述

# U230451 [USACO 05 OCT] Skiing G ## 题目背景 本题使用 `spj` ## 题目描述 $\rm Bessie$ 和农夫约翰的其他奶牛在这个冬天要去滑雪。有一天,贝西发现自己在海拔 $E(-25\le E\le25)$ 的 $R(1\le R\le100)$ 乘 $C(1\le C<\le100)$ 网格的左上角。为了加入 FJ 和其他奶牛的迪斯科派对,她必须尽快到达右下角,只能向北、向南、向东、向西行驶。 $\rm Bessie$ 开始时以初始速度 $V(1 \le V \le 10^6)$ 行驶。她发现她的速度和她的海拔变化之间有一个显著的关系。当 $\rm Bessie$ 从一个高度为 $A$ 的位置移动到相邻的 $8$ 个 $B$ 的位置时,她的速度乘以数字 $2^{(A-B)}$。Bessie从一个地点到相邻地点所需的时间是她在第一个地点时速度的倒数。 请输出 $\rm Bessie$ 到她的朋友那里所需的最小时间。 ## 输入格式 第 $1$ 行,三个整数。$V,R,C$,分别代表贝西的初始速度和网格中的行数和列数。 接下来 $R$ 行,每行 $C$ 个整数,表示网格上相应位置的海拔 $E$。 ## 输出格式 输出一个整数,输出到小数点后两位:$\rm Bessie$ 到达网格右下角的最小时间量(本题使用 `spj`,要求误差不超过 $10^{-2}$ 即可得分)。 ## 输入输出样例 #1 ### 输入 #1 ``` 1 3 3 1 5 3 6 3 5 2 4 3 ``` ### 输出 #1 ``` 29.00 ``` ## 说明/提示 ### 样例解释: 贝西的最佳路线是: - 从 $(1,1)$ 处开始,时间 $0$,速度 $1$。 - 东至 $(1,2)$ 时间 $1$ 速度 $\dfrac{1}{16}$。 - 南到 $(2,2)$ 时间 $17$ 速度 $\dfrac{1}{4}$ - 南至 $(3,2)$ 时间 $21$ 速度 $\dfrac{1}{8}$ - 东至 $(3,3)$ 时间 $29$ 速度 $\dfrac{1}{4}$
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值