P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

题目描述
Bessie is planning the annual Great Cow Gathering for cows all across the country and, of course, she would like to choose the most convenient location for the gathering to take place.

Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。

Each cow lives in one of N (1 <= N <= 100,000) different barns (conveniently numbered 1…N) which are connected by N-1 roads in such a way that it is possible to get from any barn to any other barn via the roads. Road i connects barns A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N) and has length L_i (1 <= L_i <= 1,000). The Great Cow Gathering can be held at any one of these N barns. Moreover, barn i has C_i (0 <= C_i <= 1,000) cows living in it.

每个奶牛居住在 N(1<=N<=100,000) 个农场中的一个,这些农场由N-1条道路连接,并且从任意一个农场都能够到达另外一个农场。道路i连接农场A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),长度为L_i(1 <= L_i <= 1,000)。集会可以在N个农场中的任意一个举行。另外,每个牛棚中居住者C_i(0 <= C_i <= 1,000)只奶牛。

When choosing the barn in which to hold the Cow Gathering, Bessie wishes to maximize the convenience (which is to say minimize the inconvenience) of the chosen location. The inconvenience of choosing barn X for the gathering is the sum of the distances all of the cows need to travel to reach barn X (i.e., if the distance from barn i to barn X is 20, then the travel distance is C_i*20). Help Bessie choose the most convenient location for the Great Cow Gathering.

在选择集会的地点的时候,Bessie希望最大化方便的程度(也就是最小化不方便程度)。比如选择第X个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和,(比如,农场i到达农场X的距离是20,那么总路程就是C_i*20)。帮助Bessie找出最方便的地点来举行大集会。

Consider a country with five barns with [various capacities] connected by various roads of varying lengths. In this set of barns, neither barn 3 nor barn 4 houses any cows.

1 3 4 5

@–1--@–3--@–3--@[2]

[1] |

2 | @[1] 2 Bessie can hold the Gathering in any of five barns; here is the table of inconveniences calculated for each possible location:

Gather ----- Inconvenience ------

Location B1 B2 B3 B4 B5 Total

1 0 3 0 0 14 17

2 3 0 0 0 16 19

3 1 2 0 0 12 15

4 4 5 0 0 6 15

5 7 8 0 0 0 15

If Bessie holds the gathering in barn 1, then the inconveniences from each barn are:

Barn 1 0 – no travel time there!

Barn 2 3 – total travel distance is 2+1=3 x 1 cow = 3 Barn 3 0 – no cows there!

Barn 4 0 – no cows there!

Barn 5 14 – total travel distance is 3+3+1=7 x 2 cows = 14 So the total inconvenience is 17.

The best possible convenience is 15, achievable at by holding the Gathering at barns 3, 4, or 5.

输入输出格式
输入格式:

  • Line 1: A single integer: N

  • Lines 2…N+1: Line i+1 contains a single integer: C_i

  • Lines N+2…2*N: Line i+N+1 contains three integers: A_i, B_i, and L_i

第一行:一个整数 N 。

第二到 N+1 行:第 i+1 行有一个整数 C_i

第 N+2 行到 2*N 行:第 i+N+1 行为 3 个整数:A_i,B_i 和 L_i。

输出格式:

  • Line 1: The minimum inconvenience possible

第一行:一个值,表示最小的不方便值。

输入输出样例
输入样例#1:
5
1
1
0
0
2
1 3 1
2 3 2
3 4 3
4 5 3
输出样例#1:
15

以上为题面!

思路:树形DP

转移方程:

ans[x]=ans[father]+(cnt-size[x])*z-size[x]*z;

x为当前节点,father为父节点,cnt为总人数
size[x]为以1为根x的各个儿子的人数和
z为连通当前节点与父节点的边的权值

意思就是全部人都先到1号节点,再分成两组,一组为x的儿子,一组不是x的儿子,x的儿子全部往后退一个节点,不是x的儿子全部往前进一个节点,就可以推出来当前节点的答案了!

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define N 100005
#define ll long long 

using namespace std;
int c[N];
int line[N*5];
ll size[N];
int n,m,x,y,z,tot,head,cnt;
ll ans[N],anss;
bool check[N];

struct E 
{
	int list,next,go,v;
}; E e[N*3];

void add(int xx,int yy,int zz)
{
	e[++tot].next=e[xx].list;
	e[xx].list=tot;
	e[tot].go=yy;
	e[tot].v=zz;
}

void dfs_size(int x)
{
	check[x]=true;
	for (int i=head;i>=1;i--)
	size[line[i]]+=c[x];
	for (int i=e[x].list;i;i=e[i].next)
	{
		int yy=e[i].go;
		line[++head]=yy;
		if (not(check[yy])) dfs_size(yy);
		line[head--]=0;
	}
}

void dfs_find(int x,int z)
{
	check[x]=true;
	ans[1]+=c[x]*z;
	for (int i=e[x].list;i;i=e[i].next)
	{
		int yy=e[i].go;
		int zz=e[i].v;
		if (not(check[yy]))dfs_find(yy,z+zz);
	}
}

void dfs_dp(int x,int father,int z)
{
	check[x]=true;
	if (x!=1) ans[x]=ans[father]+(cnt-size[x])*z-size[x]*z;
	if (ans[x]<anss) anss=ans[x];
	for (int i=e[x].list;i;i=e[i].next)
	{
		int yy=e[i].go;
		int zz=e[i].v;
		if (not(check[yy]))dfs_dp(yy,x,zz);
	}
}

int main()
{
	memset(e,0,sizeof(e));
	memset(c,0,sizeof(c));
	memset(line,0,sizeof(line));
	memset(ans,0,sizeof(ans));
	anss=1e15;
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	scanf("%d",&c[i]),cnt+=c[i];
	bool key=false;
	for (int i=1;i<=n-1;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	head=1;
	line[head]=1;
	memset(check,false,sizeof(check));
	if (not(key)) dfs_size(1);
	memset(check,false,sizeof(check));
	if (not(key)) dfs_find(1,0);
	memset(check,false,sizeof(check));
	if (not(key)) dfs_dp(1,0,0);
    if (not(key)) printf("%lld",anss);
}
目前尚未有 USACO Silver 2025 March 的具体题目和官方题解发布,因为该时间点可能超出了当前已有的竞赛记录范围。然而,可以基于以往的 USACO Silver 级别的题目特点以及常见的算法知识点来推测潜在的内容。 USACO Silver 级别通常涉及的数据结构和算法包括但不限于:前缀和、滑动窗口、二分查找、贪心策略、并查集、BFS/DFS 和简单动态规划等[^3]。以下是关于如何准备类似级别比赛的一些建议: ### 常见问题类型分析 #### 数据处理与模拟 一些题目会测试选手对于复杂输入的理解能力以及基本逻辑实现的能力。例如,在某些场景下需要解析多组数据或者按照特定顺序执行操作。这类问题往往不需要复杂的理论基础,但要求程序具有良好的鲁棒性和效率。 #### 贪婪算法应用 当面对资源分配类的问题时,贪婪方法通常是首选解决方案之一。通过局部最优选择逐步构建全局最佳方案是一种常见思路。比如安排奶牛吃谷物的例子就体现了这一原则[^1]。 #### 图论基础知识 图遍历技术如广度优先搜索(BFS) 或者深度优先搜索(DFS),还有最短路径计算等问题也是Silver阶段的重要组成部分。拖拉机那道题就是一个很好的例子展示了如何利用双端队列优化传统BFS过程从而提高性能表现[^2]。 ```python from collections import deque def bfs_with_deque(start_node, adjacency_list): queue = deque([start_node]) visited = set() while queue: current = queue.popleft() if current not in visited: visited.add(current) for neighbor in adjacency_list[current]: if neighbor not in visited: queue.append(neighbor) return visited ``` ### 准备建议 为了更好地应对未来的USACO赛事,推荐定期练习过往真题,并深入理解每种核心概念背后的工作机制及其适用场合。同时也要注意培养代码调试技巧,这对于快速定位错误至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值