巨木之森

链接:https://ac.nowcoder.com/acm/contest/6874/A
来源:牛客网

题目描述
调查兵团第56次壁外调查将对巨木之森展开,已知巨木之森共有nn块区域和n-1n−1条道路,保证这nn块区域联通。为了调查结果尽可能准确,兵团会派遣若干支小分队调查巨木之森,派出的小分队需满足以下规定:

1.每支小分队都可以选择从任意一块区域出发,但各支小分队的出发区域必须互不相同。

2.每支小分队都必须遍历完nn块区域。

3.每支小分队的物资消耗量为其遍历完nn块区域的路程和。

现已知调查兵团的物资总量为mm,请问最多能派遣多少支小分队参与调查?

输入描述:
第一行两个正整数nn与mm,表示巨木之森的区域数和调查兵团的物资总量,其中:n\leq10^{5}n≤10
5
,m\leq10^{18}m≤10
18

接下来n-1n−1行,每行三个正整数uu,vv,ww,表示uu号区域和vv号区域之间有一条长为ww的道路。其中:u\leq nu≤n,v\leq nv≤n,w\leq10^{8}w≤10
8

输出描述:
输出最多能派遣的小分队数量。

示例1
输入
复制
3 6
1 2 1
2 3 1
输出
复制
2
说明
从1号区域出发,遍历完3块区域,物资消耗量最少为2。

从2号区域出发,遍历完3块区域,物资消耗量最少为3。

从3号区域出发,遍历完3块区域,物资消耗量最少为2。

故最多派遣2支小分队。

这个题很明显是先求出每个点走完所有点的花费,然后把这些花费从
小到大排序,然后贪心的看能有多少个点的和小于总物资。
难点在于如何求出每个点跑完整张图的花费,如果每个点都dfs一遍
的话,肯定会超时,于是我们发现每个点的花费为这个树的直径的
2倍减去他能到达的最远距离,因为最远的距离控制的走一次,其余
的距离要走过去再返回去。
先求出树的直径,在求直径的过程中,先走到最远的点,再从这个
最远的点dfs一次,一定可以走到直径的另外的一个点,这就是这
个树的直径,再从这两个点dfs一次,每个点到这个点的距离一定有一个是这个
点能走到的最远距离,取一个大的,然后就能求出每个点的花费。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define int long long

using namespace std;

const int N = 100010, M = 2 * N;

int h[N], e[M], ne[M], w[M], idx;
int n, m;
int dist[N];
int dist1[N];
int dist2[N];

int read() {
    int s = 0, f = 0; char ch = getchar();
    while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
    while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
    return f ? -s : s;
}

void add(int a, int b, int c){
	e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
}

void dfs(int u, int father, int distance){
	dist[u] = distance;
	for (int i = h[u]; ~i; i = ne[i]){
		int j = e[i];
		if (j == father)  continue;
		dfs(j, u, distance + w[i]);
	}
}

void dfs1(int u, int father, int dist[], int distance){
	dist[u] = distance;
		for (int i = h[u]; ~i; i = ne[i]){
		int j = e[i];
		if (j == father)  continue;
		dfs1(j, u, dist, distance + w[i]);
	}
}

signed main(){
	n = read();
	m = read();
	memset(h, -1, sizeof h);
	
	int sum = 0;
	for (int i = 1; i < n; i ++){
		int a, b, c;
		a = read();
		b = read();
		c = read();
		sum += c;
		add(a, b, c), add(b, a, c);
	}
	sum *= 2;
	dfs(1, -1, 0);
	
	int u1 = 1;
	for (int i = 2; i <= n; i ++){
		if (dist[i] > dist[u1])
		u1 = i;
	}
	
	dfs(u1, -1, 0);
	
	int u2 = 1;
	for (int i = 2; i <= n; i ++){
		if (dist[i] > dist[u2]){
			u2 = i;
		}
	}
	
	dfs1(u1, -1, dist1, 0);
	dfs1(u2, -1, dist2, 0);
	
	for (int i = 1; i <= n; i ++){
		dist[i] = max(dist1[i], dist2[i]);
	}
	
	for (int i = 1; i <= n; i ++){
		dist[i] = (sum - dist[i]);
	}
	
	sort(dist + 1, dist + 1 + n);
	
	int ans = 0;
	sum = 0;
	for (int i = 1; i <= n; i ++){
		if (dist[i] + sum <= m){
			ans ++;
			sum += dist[i];
		}
	}
	
	cout << ans << endl;
//	return 0;
} 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过融合先进技术,如物联网、大数据、人工智能等,实现校园的智能化管理与服务。政策的推动和技术的成熟为智慧校园的发展提供了基础。该方案强调了数据的重要性,提出通过数据的整合、开放和共享,构建产学研资用联动的服务体系,以促进校园的精细化治理。 智慧校园的核心建设任务包括数据标准体系和应用标准体系的建设,以及信息化安全与等级保护的实施。方案提出了一站式服务大厅和移动校园的概念,通过整合校内外资源,实现资源共享平台和产教融合就业平台的建设。此外,校园大脑的构建是实现智慧校园的关键,它涉及到数据中心化、数据资产化和数据业务化,以数据驱动业务自动化和智能化。 技术应用方面,方案提出了物联网平台、5G网络、人工智能平台等新技术的融合应用,以打造多场景融合的智慧校园大脑。这包括智慧教室、智慧实验室、智慧图书馆、智慧党建等多领域的智能化应用,旨在提升教学、科研、管理和服务的效率和质量。 在实施层面,智慧校园建设需要统筹规划和分步实施,确保项目的可行性和有效性。方案提出了主题梳理、场景梳理和数据梳理的方法,以及现有技术支持和项目分级的考虑,以指导智慧校园的建设。 最后,智慧校园建设的成功依赖于开放、协同和融合的组织建设。通过战略咨询、分步实施、生态建设和短板补充,可以构建符合学校特色的生态链,实现智慧校园的长远发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值