其他分享
首页 > 其他分享> > hdu7215 Weighted Beautiful Tree

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