洛谷 P3128 [USACO15DEC]最大流Max Flow (树上差分)

博客介绍了如何利用树上差分解决USACO15DEC比赛中的最大流问题。给定一棵连接N个隔间的树形网络,以及K条牛奶运输路线,每条路线会增加沿途隔间的运输压力。任务是找出压力最大的隔间的压力值。输入包括N和K,以及树的边和运输路线信息,输出是最大压力。树上差分在此问题中起到关键作用。

FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

输入输出格式

输入格式:

 

The first line of the input contains NN and KK.

The next N-1N−1 lines each contain two integers xx and yy (x \ne yx≠y) describing a pipe

between stalls xx and yy.

The next KK lines each contain two integers ss and tt describing the endpoint

stalls of a path through which milk is being pumped.

 

输出格式:

 

An integer specifying the maximum amount of milk pumped through any stall in the

barn.

 

输入输出样例

输入样例#1: 复制

5 10
3 4
1 5
4 2
5 4
5 4
5 4
3 5
4 3
4 3
1 3
3 5
5 4
1 5
3 4

输出样例#1: 复制

9

 

给你一棵树 给你k对点 这两点之间的最短路径上的每个点权值加一 问最后最大的权值是多少

考虑树上差分,这是个裸题

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=5e4+5;
std::vector<int> G[maxn];
int dep[maxn],Fa[maxn][20],power[maxn],ans,n,m;
inline void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;Fa[u][0]=fa;
	for(int i=1;(1<<i)<=dep[u];i++)Fa[u][i]=Fa[Fa[u][i-1]][i-1];
	for(auto &v:G[u]){if(v==fa)continue;dfs(v,u);}
}
inline int lca(int x,int y)
{
	if(dep[x]<dep[y])swap(x,y);
	for(int i=19;i>=0;i--)if((1<<i)<=dep[x]-dep[y])x=Fa[x][i];
	if(x==y)return x;
    for(int i=19;i>=0;i--)if(Fa[x][i]!=Fa[y][i])x=Fa[x][i],y=Fa[y][i];
    return Fa[x][0];
}
inline void solve(int u,int fa)
{
	for(auto &v:G[u])
	{
		if(v==fa)continue;
		solve(v,u);
		power[u]+=power[v];
	}
	ans=max(ans,power[u]);
}
inline int dis(int x,int y){return dep[x]+dep[y]-dep[lca(x,y)];}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++)
	{
		int u,v;scanf("%d%d",&u,&v);
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	dfs(1,0);
	while(m--)
	{
		int x,y;scanf("%d%d",&x,&y);
		power[x]++;power[y]++;power[lca(x,y)]--;power[Fa[lca(x,y)][0]]--;
	}
	solve(1,0);
	printf("%d\n", ans);
	return 0;
}

 

<think>好的,我现在需要帮用户推荐洛谷平台上关于树上差分的练习题。首先,我得回忆一下树上差分的基本概念和应用场景。树上差分通常用于处理树上的路径更新,比如给某条路径上的所有节点增加一个值,然后通过后续的DFS来统计每个节点的最终值。点差分和边差分的主要区别在于处理路径端点的方式,点差分需要考虑LCA(最近公共祖先)的处理。 接下来,我需要确定用户的需求。用户明确提到要找洛谷的练习题,特别是关于树上差分的。因此,我需要找出洛谷上那些使用点差分的典型题目。记得之前处理过类似的问题,可能有一些常见的题目,比如P3128 [USACO15DEC]Max Flow P,这道题就是典型的点差分应用,要求统计每个点被覆盖的次数。另外,P3258 [JLOI2014]松鼠的新家也是一个点差分的例子,因为需要处理路径上的点权变化,同时要注意重复点的处理。 然后,我还需要确保这些题目确实在洛谷上存在,并且标签或题解中提到了树上差分。可能需要检查题目的标签,比如“树上差分”、“LCA”等。例如,P2680 [NOIP2015 提高组] 运输计划,虽然主要考察二分答案和树上差分结合,但其中涉及边差分,不过有时也可能需要点差分的思路,或者用户可能通过这道题加深对差分的理解。不过需要确认这道题是否属于点差分,可能用户需要的是更直接的点差分题目,所以可能需要优先推荐P3128和P3258。 另外,用户可能需要不同难度的题目,从入门到提高。P3128USACO的题目,可能难度适中。而P3258是省选/NOI-级别的,稍微难一些。还有P5836 [USACO19DEC]Milk Visits S,可能涉及路径统计,但需要确认是否使用点差分。 还要考虑题目的正确性和是否可用点差分解决。比如,松鼠的新家中,每次移动路径上的点都需要加1,但起点和终点可能有重复,这时候需要在LCA处进行调整,这正是点差分的处理方式。因此,这道题是很好的练习。 最后,总结这些题目,按难度排序,并给出简要说明,帮助用户选择适合的练习。同时,提醒用户掌握前置知识,如LCA算法和DFS遍历,以便更好地解题。可能还需要检查是否有其他推荐题目,比如P1600 [NOIP2016 提高组] 天天爱跑步,但这道题难度较高,可能涉及更复杂的情况,是否适合作为点差分的练习题需要斟酌,可能暂时不推荐,除非用户有更高需求。</think>树上差分的应用场景和洛谷题库特点,为你推荐以下5道经典练习题,按难度由浅入深排列: --- ### 一、基础应用 **P3128 [USACO15DEC]Max Flow P** 要求统计树上所有点被路径覆盖次数的最大值。典型点差分模板题,需对每条路径做$u \to v$的差分标记,最后通过DFS求和[^1] `标签:LCA/树上差分/DFS` --- ### 二、端点特殊处理 **P3258 [JLOI2014]松鼠的新家** 处理路径上连续点权变化,需注意路径端点重复计算问题。关键代码段: ```cpp diff[u]++, diff[v]++; diff[lca]--, diff[fa[lca][0]]--; // 注意父节点处理 ``` `标签:树链剖分/树上差分` --- ### 三、结合贪心思想 **P3582 [POI2015] KIN** 在树形结构上动态维护路径权值,需结合贪心选择策略使用点差分统计信息 `标签:贪心/树上差分` --- ### 四、进阶综合题 **P2680 [NOIP2015 提高组] 运输计划** 结合二分答案验证,使用点差分统计不符合条件的路径交,考察对差分标记的逆向应用能力[^2] `标签:二分答案/LCA/树上差分` --- ### 五、特殊场景扩展 **P5836 [USACO19DEC]Milk Visits S** 统计路径上特定类型节点的存在性,可转化为点差分预处理路径特征值 `标签:并查集/树上差分` --- **练习建议**: 1. 先掌握`LCA倍增算法`和`DFS遍历`的前置知识 2. 解题时注意区分点差分与边差分的标记差异: $$ \begin{cases} \text{点差分:} & diff[u]++, diff[v]++, diff[lca]--, diff[fa[lca]]-- \\ \text{边差分:} & diff[u]++, diff[v]++, diff[lca]-=2 \end{cases} $$ 3. 推荐配合使用`重链剖分`优化LCA查询效率
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值