P3874 [TJOI2010]伐採

典型的なツリー-DPは、それがアクリジンませんが、それはそう、問題への解決策に依存します。

トピックの背景

\(A \)果樹園では、果樹の木がいっぱい見つかったので、彼は悪い考えをプレイし、彼が家に取るために木の部分をカットしていきます。

タイトル説明

私たちは、任意の2点のみ1パスの間、つまり、ツリー構造として表現ツリーを置くことができます。各点で\(Iは\)フルーツとの接合部の両方で、各果実は、値有する\(V_I \)および体重\を(W_i \) \(\)の木(または全て)の一部を奪うようにしたい、少なくとも含む\(K \)のノード(つまり、少なくとも\(K \)果物)を、可能な限り高いこれらの果物の平均値。平均値は、果実の総重量で割った値の合計値です。小さいことに留意されたい\(A \)カット・ツリーは、元のツリー内の通信の一部でなければなりません。

入力形式

最初の行は二つの数字含ま\(N \)\(K \)を、それぞれ、小ツリー内のノードの数\(\)果実の数は少なくとも離れなければなりません。第二行は離間スペースが含まれている\(N \)数は、それぞれ、果実の各接続点の値表す\を(V_I \) 第三行は分離スペースが含まれている\(N \)数、それぞれ、各果実の重量\(W_i \) ダウンプレス\(N-1 \)行、2つの数値を含む各行\(a_iを\)\(B_i \)(\ (1≤a_iを、B_i≤N \)ノードで表される)、\(a_iを\ )\(b_i \)の間にエッジが存在します。入力は、適切なツリー構造であることが保証します。

出力フォーマット

可能な最大値の平均を表す数を含む出力一行。2小数点以下の桁に丸め。

データ範囲

以下のための\(100%\)データ、\(1≤N≤100 ,. 1≤K≤N、V_I。10000≤1≤、W_i。1≤≤10000 \)

解決

私はこれが知っている、値や体重を参照してください。私はしません通常、バックパックが提供されてもよい木ナップザック問題。\(F_ {I}を\)選択を表す以下で秤量しない\(J \)を得ることができるアイテムの最大値が、ツリー構造を結合するために、この質問、および\(Wを\ )\(Vの\)範囲が大きく、それが設定された条件の数に基づいて考えられています。

我々は、セット\は(F_ {I、Jは} \) することを示している(私は\)\選択されたルートとするサブツリー\(J \)最大平均値ポイントは、そのMeikeサブツリー、我々片得ることができますどのくらい節転移を選ぶため。

タイトルレコード平均、および平均の直接転送が容易ではないので※、私たちはします(F \)\開口にアレイ構造を、レコード、合計値の合計重量、および平均値の現在の状態の合計量(合計値/ )。この質問は明らかに木である\(01 \)バックパック、その外側のループを逆にすることを忘れないでください。

struct node {
    double w, v, ave;//重量,权值,平均值
    node() {}
    node(double a, double b, double c) : w(a), v(b), ave(c) {}
}f[105][105];

void dfs(int now, int father) {
    f[now][1] = node(w[now], v[now], v[now] / w[now]);//为了维护连通性,根节点肯定要选.
    for (int i = head[now]; i; i = nxt[i]) {
        if (to[i] == father)//枚举每个子节点
            continue;
        dfs(to[i], now);//先递归下去,再由叶到根更新
        for (int j = n; j > 1; --j) {//枚举以now为根的子树中一共选择多少个点,注意01背包要倒序
            for (int k = 1; k <= j; ++k) {//枚举当前子树中选择了j个节点中的多少个
                node p = f[to[i]][j - k];//在这个子树中选择了j个节点中的j-k个点
                node q = f[now][k];//在其他子树中选择了k个点.
                double ave = (p.v + q.v) / (p.w + q.w);//计算平均值
                if (ave >= f[now][j].ave) {//更新答案
                    f[now][j] = node(p.w + q.w, p.v + q.v, ave);
                }
            }
        }
    }
    return;
}

最後に、すべての\(F [I] [J ](\ルJ \ルNをK)\)が出力する最大値を選択します。

気持ちはそうではありません

おすすめ

転載: www.cnblogs.com/i-cookie/p/11434173.html