hdu7215 Weighted Beautiful Tree
作者:互联网
problem
一个点的点权的可能为不变或者变为连着的边的边权。
然后dp、
dp[u][0]表示变成大于等于w[u]边的最小代价。
dp[u][1]表示变成小于等于w[u]边的最小代价。
然后对边权排序。
一段连续的是使用dp[][0]的和
一段连续的是使用min(dp[][0],dp[][1])的和
一段连续的是使用dp[][1]的和
初始化是不变和变为u和父亲的边权两种。
code
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define int long long
using namespace std;
const int _=1e5+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
// const int mod=1e9+7;
int n,c[_],w[_],dp[_][2];
vector<array<int,2>> G[_];
int f(int pos,int val) {return c[pos]*abs(val-w[pos]);}
int tot[_][2];
void dfs(int u,int fa,int fake) {
vector<int> V,Q;
for(auto x:G[u]) {int v=x[1],q=x[0];if(v==fa) continue;
dfs(v,u,q);
V.push_back(v);
Q.push_back(q);
}
int nbnb=f(u,fake);
for(auto x:G[u]) {int v=x[1],q=x[0];if(v==fa) continue;
if(q==fake) nbnb+=min(dp[v][0],dp[v][1]);
if(q>fake) nbnb+=dp[v][1];
if(q<fake) nbnb+=dp[v][0];
}
dp[u][0]=dp[u][1]=nbnb;
int tmp=0;
for(auto x:G[u]) {int v=x[1],q=x[0];if(v==fa) continue;
if(q==w[u]) tmp+=min(dp[v][0],dp[v][1]);
if(q>w[u]) tmp+=dp[v][1];
if(q<w[u]) tmp+=dp[v][0];
}
if(w[u]==fake) dp[u][0]=dp[u][1]=min(tmp,nbnb);
else if(w[u]>fake) dp[u][1]=min(dp[u][1],tmp);
else dp[u][0]=min(dp[u][0],tmp);
// printf("dp[%d][%d]=%d,dp[%d][%d]=%d\n",u,0,dp[u][0],u,1,dp[u][1]);
if(V.size()==0) return;
// array<int,2> tot[V.size()];
// vector tot(V.size(),vector<int>(2,0));
int len=V.size();
for(int i=0;i<len;++i) tot[i][0]=((i!=0) ?tot[i-1][0]:0)+dp[V[i]][0];//,cout<<tot[i][0]<<" ";cout<<"\n";
for(int i=len-1;i>=0;--i) tot[i][1]=((i!=len-1)?tot[i+1][1]:0)+dp[V[i]][1];//,cout<<tot[i][1]<<" ";cout<<"\n";
for(int i=0;i<len;++i) {
int l=i,r=i;
while(r+1<len && Q[r+1] == Q[l]) r++;
int tmp=0;
for(int j=l;j<=r;++j) tmp+=min(dp[V[j]][0],dp[V[j]][1]);
int x=(l-1<0) ? 0 : tot[l-1][0];
int y=(r+1>=len)? 0 : tot[r+1][1];
// printf("[%d,%d]\n",l,r);
// cout<<(Q[l]>=fake)<<"?\n";
if(Q[l]==fake) dp[u][0]=min(dp[u][0],x+tmp+y+f(u,Q[l])),
dp[u][1]=min(dp[u][1],x+tmp+y+f(u,Q[l]));
else if(Q[l]>fake) dp[u][1]=min(dp[u][1],x+tmp+y+f(u,Q[l]));
else dp[u][0]=min(dp[u][0],x+tmp+y+f(u,Q[l]));
i=r;
}
}
void solve() {
n=read();
FOR(i,1,n) c[i]=read();;
FOR(i,1,n) w[i]=read();
FOR(i,1,n) G[i].clear();
FOR(i,1,n-1) {
int u,v,q;
u=read(),v=read(),q=read();
G[u].push_back({q,v});
G[v].push_back({q,u});
}
FOR(i,1,n) sort(G[i].begin(), G[i].end());
dfs(1,0,0);
cout<<dp[1][1]<<"\n";
// exit(0);
}
signed main() {
// freopen("1007.in","r",stdin);
// freopen("a.out","w",stdout);
int T=read();
while(T--) solve();
return 0;
}
标签:Beautiful,hdu7215,min,int,Tree,tot,read,fake,dp 来源: https://www.cnblogs.com/acmnb/p/16586020.html