题解:P10974 Accumulation Degree
wangbinfeng · · 题解
这不一眼换根 DP,然后我尝试不用编译器一遍过(也许算成功吧?3 次 CE、1 次 RE),感觉没难度。别被蓝题吓到了,其实挺简单的。
考虑下图(鸣谢 Graph Editor 生成图片):
显然,
暴力做法很容易想到:枚举根节点,对于每个根节点,DFS 计算出其对应的结果,取所有结果的最大值作为答案即可。但是时间复杂度为
注意到,计算完
经过分析得出,
注意到
就完了,时间复杂度为
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=200000+9,inf=0x3f3f3f3f3f3f3f3fLL;
vector<vector<pair<int,int>>>g;
int n,dp[maxn],ans;
inline int dfs1(const int u,const int fa){
for(const auto[v,w]:g[u])if(v!=fa)dp[u]+=min(dfs1(v,u),w);
return dp[u]==0?inf:dp[u];
}
inline void dfs2(const int u,const int fa,const int sum){
ans=max(ans,sum);
for(const auto[v,w]:g[u])if(v!=fa){
if(g[u].size()==1)dfs2(v,u,dp[v]+w);
else dfs2(v,u,dp[v]+min(sum-min(dp[v],w),w));
}
}
signed main(){
static int T=-1;
if(T==-1){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
cin>>T;
}
if(T--==0)return 0;
cin>>n,ans=0,g.resize(n+9),g.clear(),memset(dp,0,sizeof dp);
for(int i=1,u,v,w;i<n;i++)cin>>u>>v>>w,g[u].push_back({v,w}),g[v].push_back({u,w});
dfs1(1,-1),dfs2(1,-1,dp[1]);
cout<<ans<<'\n';
main();
}
- UPD. 2024 年 12 月 13 日进行订正,发现之前写的内容出现了不少错误,而作者本人由于已经 AFO 了一个季度,没有怎么接触 OI 导致也一时看不懂自己写的题解(诚挚地向之前阅读本提题解的同学道歉,还是写的太烂了)。如果还有错误希望能得到指出!