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;
}