牛客 6874 A - 巨木之森 (树的直径)

链接 : A - 巨木之森

在这里插入图片描述
题意:
每支小队从每个点出发 ,遍历完整颗树的花费是走过路径的和,要求在花费 m 以内,最多可以有多少个小队遍历完整颗树。
思路:

  1. 可以求出每个点遍历整棵树的花费 ,排个序,从小到大选就好了,关键在于求花费。
  2. 可以发现,要想遍历完整颗树,再回到原来的位置,那么就要把每条边都走两遍,但是现在不需要回到原来的位置,所以只要找到离根节点最远的点,用总权值的两倍减去 这条最远边的长度就好了。
  3. 根据树的一个性质,离某个点最远的点一定是树直径两端点中的一个,所以我们只要求出树的直径的两个端点,然后得到其他点到这两个点的距离就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 7;
int head[maxn],num,n,ans,pos;
ll sum,w,dis[maxn][2],val[maxn],m;
struct node{
       ll to,next;
       ll w;
}e[maxn];
void add(ll u,ll v,ll w){
     e[num].next = head[u];
     e[num].to = v;
     e[num].w = w;
     head[u] = num ++;
}
void dfs(int u,int pre,int id){
     if(dis[u][id] > dis[pos][id]) pos = u;
     for(int i = head[u]; i != -1; i = e[i].next){
         ll to = e[i].to;
         ll w = e[i].w;
         if(to == pre) continue;
         dis[to][id] = dis[u][id] + w;
         dfs(to,u,id);
     }
}
int main() {
    memset(head,-1,sizeof(head));
    scanf("%lld%lld",&n,&m);
    for(ll i = 0,u,v; i < n - 1; i ++){
        scanf("%lld%lld%lld",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
        sum += 2 * w;
    }
    pos = 1;
    dfs(1,-1,0);
    dis[pos][0] = 0;
    dfs(pos,-1,0);
    dfs(pos,-1,1);
    for(int i = 1; i <= n; i++){
        val[i] = sum - max(dis[i][1],dis[i][0]);
    }
    sort(val + 1,val + n + 1);
    ll res = 0;
    for(int i = 1; i <= n; i++){
         if(res+val[i]<=m){
            res+=val[i];
            ans++;
        }
        else break;
    }
    printf ("%d\n",ans);
}
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法与数据结构,如二叉、哈希表、红黑等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法和数据结构进行有效地结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值