树形dp——游族杯 D

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树形dp——游族杯 D相关的知识,希望对你有一定的参考价值。

只有三种情况:全是1,有一个2的,只有一个点的

树形dp求最长的1链,或者带一个2的最长1链即可

#include<bits/stdc++.h>
#define rep(i,x,y) for(auto i=(x);i<=(y);++i)
#define dep(i,x,y) for(auto i=(x);i>=(y);--i)
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int N=2e6+10;
const int inf=1e9;
const int mo=998244353;
int l1=1,l2=1,fa[N],f[N],g[N],a[N];
vector<int>p[N];
void dfs(int x){
    if(a[x]==1)f[x]=1;else f[x]=0; // 不许有2
    if(a[x]<=2)g[x]=1;else g[x]=0;// 允许有一个2
    for(auto&i:p[x])if(i!=fa[x]){
        fa[i]=x;dfs(i);
        if(a[x]==1){
            l1=max(l1,f[i]+f[x]);
            l2=max(l2,max(f[i]+g[x],g[i]+f[x]));
            f[x]=max(f[x],f[i]+1);
            g[x]=max(g[x],g[i]+1);
        }
        if(a[x]==2){
            l2=max(l2,f[i]+g[x]);
            g[x]=max(g[x],f[i]+1);
        }
    }
}
int main(){int n;
    scanf("%d",&n);
    rep(i,2,n){int x,y;
        scanf("%d%d",&x,&y);
        p[x].push_back(y);p[y].push_back(x);
    }int mi=inf;
    rep(i,1,n){
        scanf("%d",&a[i]);
        mi=min(mi,a[i]);
        if(!a[i]){
            printf("0/1
");return 0;
        }
    }
    if(mi>1){
        printf("%d/1
",mi);return 0;
    }
    dfs(1);
    if(l2<=l1*2)printf("1/%d
",l1);
    else{
        cout<<2<</<<l2<<
;
    }
}

 

以上是关于树形dp——游族杯 D的主要内容,如果未能解决你的问题,请参考以下文章

EOJ-2020“游族杯”Coronavirus Battle (CDQ分治枚举优化)

2020 年 “游族杯” 全国高校程序设计网络挑战赛

2021陕西省赛 D.Disease(树形dp&期望dp)

2021陕西省赛 D.Disease(树形dp&期望dp)

2019年杭电多校第九场07题(HDU6686+树形dp)

BZOJ-3573米特运输 树形DP