树形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\n");return 0;
        }
    }
    if(mi>1){
        printf("%d/1\n",mi);return 0;
    }
    dfs(1);
    if(l2<=l1*2)printf("1/%d\n",l1);
    else{
        cout<<2<<'/'<<l2<<'\n';
    }
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12945010.html