ツリー最小エッジカバー問題

1077宮殿ガード

ボブは、特に戦略的なゲーム、コンピュータゲームをプレイするのが好き、時には彼は、彼は非常に悲しい作っ問題の解決策を見つけることができません。
彼は今、次のような問題があります。
彼は中世の都市、都市道路、これはツリーを構成を保護する必要があります。
各ノード上の兵士たちは、すべての接続点とエッジことが観察されてもよいです。
彼らはすべての側面を観察することができるように、彼は、ノード上の兵士の最小数を配置する必要があります。
あなたは彼を助けることはできますか?
例えば、次のツリー:

のみ(ノード1で)兵士を配置するために、すべてのエッジを観察することができます。
入力フォーマット
入力テストデータが複数組、木を記述するために使用されるテストデータの各セットを含みます。
各試験のために、最初の行は、整数N、ツリーのノードの数を含んでいます。
次のように次のN行は、各行はノードを記述する。
子ノード:(ノード番号)...子ノードの子ノードの数
は0からN-1のノード番号は、以下10の各ノードの子ノードの数は、各エッジは、入力データに一度だけ現れます。
出力フォーマット
各テストケースについて、行を占めるの出力結果は、兵士の最小必要数を表します。
データ範囲
0 <N≤1500
入力サンプル:
4
0:(1)1
1:(2)2 3
2:(0)
3:(0)
5。
3:(3)1 4 2
1:(1)0
2:(0)
0(0)
4:(0)
出力サンプル:
1
2

片側のため、親ノードまたは子ノードのカバレッジによって覆われていてもよい、F [U] [0]、F、ノードホールド兵士ことを示している[U] [1]ノード兵士放電ことを示している。
のみ、場合ホールドノード放電からここですべての子ノードに転送され、放電ノード、子が又は残すノードから転送されてもよい場合は

#include<bits/stdc++.h>
using namespace std;
const int N=1510;
int h[N],idx,f[N][2];//0不放,1放
struct eg{
    int v,nex;
}e[N*2];
void add(int u,int v){
    e[idx]={v,h[u]};
    h[u]=idx++;
}
void dfs(int u,int pre){
    f[u][1]=1;
    f[u][0]=0;
    for(int i=h[u];~i;i=e[i].nex){
        int v=e[i].v;
        if(pre==v) continue;
        dfs(v,u);
        f[u][0]+=f[v][1];
        f[u][1]+=min(f[v][1],f[v][0]);
    }
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        memset(h,-1 ,sizeof h); idx=0;
        for(int i=1;i<=n;++i){
            int u,k,v;
            scanf("%d:(%d)",&u,&k);
            while(k--){
                scanf("%d",&v);
                add(u,v);
                add(v,u);
            }
        }
        dfs(0,-1);
        if(n==1) cout<<1<<endl;
        else 
        cout<<min(f[0][1],f[0][0])<<endl;
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/jjl0229/p/12655305.html