羅区P2015バイナリ多分岐りんごりんご&問題への解決策yzoj1856

バイナリ

マルチフォーク

リンゴの木は、分岐した分岐がある場合、多分岐点、分岐番号k> = 0(すなわち、以上息子0のノードの数)N、総ツリーノード(リーフ分岐又は分岐点が存在してもよいですポイント)、根は数値である必要があり、1〜Nの番号が付け。彼は我々の立場のブランチノードブランチ接続の両端の数を説明しました。

データスケール:

データを満たす1の20%<= N <= 15。

データを満たす1の40%<= N <= 100。

データを満たす1 <= N <= 310、C <= 2 ^ 31-1の100%まで。

F [X]サブツリーのルートとのX、Y保持表される[Y]はリンゴの最大数、容易に推定される状態遷移方程式エッジようDPツリー二つの質問、同じコードは、詳細を介して変更することができます

F [X] [[T] = MAX(F [X] [T]、F [X] [TJ-1] + F [Y] [J] +エッジ[i])と

Y [i]は示しX-> FとYリンゴこのエッジは、[X] [TJ-1]の代わりにFの[X] [TJ]我々が予約しているため、Xの子ノード、エッジであることを特徴としますX-> Y、このエッジは、最後の01バックパックは、列挙を逆転させることができます。

バイナリコードのリンゴの木

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=110;
int n,q,f[maxn][maxn];
int head[maxn],Next[2*maxn],ver[2*maxn],edge[2*maxn],tot,u,v,z;
void add(int x,int y,int z){
    ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
}
void dp(int x,int fa){
    for(int i=head[x];i;i=Next[i]){
        int y=ver[i];
        if(y==fa) continue;
        dp(y,x);
        for(int t=q;t>=1;--t){
            for(int j=t-1;j>=0;--j){
                f[x][t]=max(f[x][t],f[x][t-j-1]+f[y][j]+edge[i]);
            }
        }
    }
}
int main(){
    scanf("%d %d",&n,&q);
    for(int i=1;i<n;++i){
        scanf("%d %d %d",&u,&v,&z);
        add(u,v,z);
        add(v,u,z);
    }
    dp(1,0);
    printf("%d",f[1][q]);
    return 0;
}

マルチブランチリンゴの木コード

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=330;
int n,q;
long long f[maxn][maxn];
int head[maxn],Next[2*maxn],ver[2*maxn],edge[2*maxn],tot,u,v,z;
void add(int x,int y,int z){
    ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
}
void dp(int x,int fa){
    for(int i=head[x];i;i=Next[i]){
        int y=ver[i];
        if(y==fa) continue;
        dp(y,x);
        for(int t=q;t>=1;--t){
            for(int j=t-1;j>=0;--j){
                f[x][t]=max(f[x][t],f[x][t-j-1]+f[y][j]+(long long)edge[i]);
            }
        }
    }
}
int main(){
    scanf("%d %d",&n,&q);
    for(int i=1;i<n;++i){
        scanf("%d %d %d",&u,&v,&z);
        add(u,v,z);
        add(v,u,z);
    }
    dp(1,0);
    printf("%lld",f[1][q]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/donkey2603089141/p/11414670.html