F. Maximum White Subtree——(树形DP-最大子树权值和)

总结

树是一种特别优美得结构

树形DP的题,是我打CF以来第一次遇到的,不会,不知道,那就学,学了一个最大子树和,发现用到这个题,只需要再跑一次DFS,统计一下答案就行,只不过我比较笨,统计每个位置的最优解,判断的条件有点多,不过还是比较稳,没WA,他们说什么换根,俺也不懂,那就学吧。

题目链接

//#pragma GCC optimize(2)
#include
//typedef long long ll;
//#define ull       unsigned long long
#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<
#define eps         1e-6
#define lowbit(x)   (x&(-x))
#define PI          acos(-1.0)
#define inf         0x3f3f3f3f
#define MAXN        0x7fffffff
#define INF         0x3f3f3f3f3f3f3f3f
#define pa          pair
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("cin.txt","r",stdin);
    //  freopen("cout.txt","w",stdout);
#endif
}
const int N=2e5+5;
vector<int>G[N];
int dp[N],ans[N],a[N];
void dfs(int u,int fat)
{
    dp[u]=a[u];
    int len=G[u].size();
    for(int i=0;i<len;++i)
    {
        int v=G[u][i];
        if(v!=fat)
        {
            dfs(v,u);
            if(dp[v]>=0)
                dp[u]+=dp[v];
        }
    }
}
void dfs_(int u,int fat)
{
    if(dp[u]>=0)
    {
        if(ans[fat]>=0)
        {
            if(dp[u]>=ans[fat])
                ans[u]=dp[u];
            else
                ans[u]=ans[fat];
        }
        else
            ans[u]=dp[u];
    }
    else
    {
        if(ans[fat]>=0)
            ans[u]=dp[u]+ans[fat];
        else
            ans[u]=dp[u];
    }
    int len=G[u].size();
    for(int i=0;i<len;++i)
    {
        int v=G[u][i];
        if(v!=fat)
        {
            dfs_(v,u);
        }
    }
}
signed main()
{
    IOS;
    //file();
    int n;
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        int x;
        cin>>x;
        a[i]=(x==1?1:-1);
    }
    for(int i=1;i<n;++i)
    {
        int x,y;
        cin>>x>>y;
        G[x].pb(y);
        G[y].pb(x);
    }
    dfs(1,0);
    dfs_(1,0);
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<" ";
    cout<<endl;
    return 0;
}

你可能感兴趣的:(#,树形DP)