経済的困難CodeForces - 1263F(DP)

メインと予備:バーランド宮殿における配電網2つのグリッドから成ります。宮殿内のワイヤはとても良いでしょうそれらのいくつかを販売、高価な材料で作られています!
ここに画像を挿入説明
(メインと予備)各グリッドは、ヘッドノードを有する(その数は1です)。他のすべてのノードは、ヘッドノードから電気を取得します。各ノードは、一意のパスでヘッドノードから到達することができます。また、両方のグリッドがさらに広がるない電気を行うちょうどnノードを、持っています。

換言すれば、すべてのグリッド1.各ツリーは独立列挙し、別のグリッドのノードに接続されていない1つのグリッドからノードを有するノード数のルート、を有するn葉に根ざし向け木です。

また、宮殿は、n個の電気機器を有しています。各デバイスは、メイングリッドの一方のノードでリザーブグリッドの一方のノードに接続されています。デバイスは、そこから電気が(これらのノードは、ツリーの葉です)さらに広がっていない、ノードにのみ接続します。各グリッドの葉は、正確に一つのデバイスに接続されています。

この例ではメイングリッドは、6つのノード(トップ・ツリー)を含み、予備グリッドは、4つのノード(下位ツリー)を含みます。青に着色された数字と3つのデバイスがあります。
全グリッド(2つのグリッド及びnデバイス)(上の写真のように)、このように示すことができることが保証されます。

メイングリッドは、そのワイヤ「下に上から」向けられ、上部木、ある
予備グリッドワイヤ、「トップにダウンから」導かれる低い木、ある
2つのグリッド間の水平方向の行である-装置左から右に1からnまでの番号、
ノード間の配線が交差しません。
正式には、各ツリーのために、番号1のノードから深さ優先探索が存在する訪問葉デバイスへの接続の順に1,2、...、N(まず、装置1に接続されたノード、次いで等装置2に接続されたノード)。

各デバイスは、少なくとも1つのグリッド(メインまたは予備)から電力を供給されるように、ビジネスマンは、ワイヤの販売する(削除)する最大量を望んでいます。換言すれば、デバイスごとに1つのグリッドのノードのみを含み(メイングリッドまたは予備グリッド)ヘッドノードへの少なくとも一つの経路に存在するべきです。

入力
宮殿内のデバイスの数-最初の行は、整数n(1≤n≤1000)を含みます。

次の行は、(1 +n≤a≤1000+ n)は整数含ま - メイングリッド内のノードの量。

次の行は、1整数PI(1≤pi≤a)を含みます。メイングリッドは、(i + 1)番目のPI番目のノードからのワイヤが含まれていることを各整数PI手段。

i番目のデバイスに接続されているメイングリッド内のノードの数 - 次の行は、n整数XI(1≤xi≤a)を含みます。

予備グリッド内のノードの量 - 次の行は、整数bを(1 +n≤b≤1000+ N)を含みます。

次の行は、B-1の整数チー(1≤qi≤b)を含みます。予備グリッドは、(i + 1)番目の気番目のノードからのワイヤが含まれていることを各整数チー手段。

i番目のデバイスに接続されている予備グリッド内のノードの数 - 次の行は、n個の整数のYI(1≤yi≤b)を含みます。

各グリッドが正確にn個の葉を持つ木、であり、各葉は、1つのデバイスに接続されていることが保証されています。また、その訪問の葉は、デバイスへの接続のために、各ツリーのノード1から深さ優先探索が存在することが、保証されます。

出力は、
単一の整数を印刷する-各デバイスに電力が供給されるように切断することができるワイヤの最大量。


入力
3
6
4 1 1 4 2
6 5 3
4
1 1 1
2 3 4
の出力
5
入力
4
6
4 4 1 1 1
3 2 6 5
6
6 6 1 1 1
5 4 3 2
出力
6
入力
5
14
1 1 11 2 14 14 13 7 12 2 5 6 1
9 8 3 10 4
16
11 10 10 2 5 10 1 14 3 7 11 6 12 2
8 16 13 4 15
出力
17

最初例えば、示すもの下図可能な解の(除去することができるワイヤは赤色でマークされています)。

ここに画像を挿入説明
第二及び第三の例を以下に見ることができます。
ここに画像を挿入説明

質問の意味:
2つのツリーを、n個の葉の各ツリーは、各マシンに接続されています。
彼は、各マシンが道路外出1番ノードを(2つのツリーのルートノードが1番ノードである)を有するように、点のほとんどを除去することを要求されました。
アイデア:
n≤1000、手段n個のパーティー。
この質問は、バックパックに似ている、いくつかの項目を選択し、連続追加収入があるでしょう。
集合Lは、ツリーアレイの各点のRが機械に接続されている最も左(右)側を表します。
どのように多くの側面その後、設定ヴァル[0/1] [X] [ y]は、ほとんど削除する選択のx〜yのタイムマシンを表します。
DFSこれらの配列は、それを維持するために使用することができます。
その後、N-できる2シフト。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int maxn = 2005;

vector<int>G[2][maxn];
int l[2][maxn],r[2][maxn],siz[2][maxn],val[2][maxn][maxn];
int dp[maxn];

void dfs(int num,int u)
{
    if(u != 1)siz[num][u] = 1;
    for(int i = 0;i < G[num][u].size();i++)
    {
        int v = G[num][u][i];
        dfs(num,v);
        l[num][u] = min(l[num][u],l[num][v]);
        r[num][u] = max(r[num][u],r[num][v]);
        siz[num][u] += siz[num][v];
    }
    val[num][l[num][u]][r[num][u]] = max(val[num][l[num][u]][r[num][u]],siz[num][u]);
}

int main()
{
    int n;scanf("%d",&n);
    for(int num = 0;num <= 1;num++)
    {
        int a;scanf("%d",&a);
        for(int i = 1;i <= a;i++)
        {
            l[num][i] = a + 1;
            r[num][i] = 0;
        }
        for(int i = 2;i <= a;i++)
        {
            int x;scanf("%d",&x);
            G[num][x].push_back(i);
        }
        for(int i = 1;i <= n;i++)
        {
            int x;scanf("%d",&x);
            l[num][x] = i;
            r[num][x] = i;
        }
        dfs(num,1);
    }
    for(int i = 1;i <= n;i++)
    {
        for(int j = i;j <= n;j++)
        {
            dp[j] = max(dp[j],dp[i - 1] + max(val[0][i][j],val[1][i][j]));
        }
    }
    printf("%d\n",dp[n]);
    return 0;
}
公開された676元の記事 ウォン称賛18 ビュー30000 +

おすすめ

転載: blog.csdn.net/tomjobs/article/details/104125141