1 条题解
-
1
#include <bits/stdc++.h> #define ll long long #define P 998244353 using namespace std; const int N=205; int n,m,tot,k,s,t,sz[N],a[N],de[N],D[N];//D:以u为根的子树的最大深度 ll f[N],g[N],sum[N],S[N],F[N];//S:后缀sum和 F:后缀f和 vector<int> e[N]; struct node{ int sz;ll sum;int id; bool operator<(const node &k)const{ return (2*sz)*k.sum<=(2*k.sz)*sum; } }b[N]; void dfs(int u){ sz[u]=1;sum[u]=a[u]; if (e[u].size()==0){ f[u]=g[u]=0; return; } for (int &v:e[u]){ D[v]=de[v]=de[u]+1; dfs(v); sum[u]+=sum[v]; sz[u]+=sz[v]; D[u]=max(D[u],D[v]); } tot=0; for (int &v:e[u]) b[++tot]={sz[v],sum[v],v}; sort(b+1,b+1+tot); ll ti=0; S[tot+1]=F[tot+1]=0; for (int i=tot;i>=1;--i){ int v=b[i].id; S[i]=S[i+1]+sum[v];//后缀sum和 F[i]=F[i+1]+(sum[v]+f[v]+2*sz[v]*S[i+1]);//后缀f } for (int i=1;i<=tot;++i){ int v=b[i].id; if (D[v]==D[u]){//v是最深点 考虑最后走v g[u]=min(g[u],f[u]+ti*S[i+1]+F[i+1]+((sz[u]-sz[v]-1)*2+1)*sum[v]+g[v]); } f[u]+=(ti+1)*sum[v]+f[v]; ti+=sz[v]*2; } } int main(){ int T; cin>>n>>T; for (int i=2;i<=n;++i){ cin>>s>>a[i]; e[s].push_back(i); } memset(g,0x3f,sizeof(g)); dfs(1); if (T) cout<<2*n-2-D[1]<<' '<<g[1]; else cout<<2*n-2<<' '<<f[1]; }
- 1
信息
- ID
- 498
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 26
- 已通过
- 5
- 上传者