ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

hdu7215 Weighted Beautiful Tree

2022-08-14 19:03:02  阅读:145  来源: 互联网

标签:Beautiful hdu7215 min int Tree tot read fake dp


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有