状态表示:
对于任意一条边,要么在父亲放士兵,要么在儿子放士兵。
(f(u,0)):以(u)为根的子树在(u)上不放置的士兵的情况下,最少所需的士兵数目。
(f(u,1)):以(u)为根的子树在(u)上放置的士兵的情况下,最少所需的士兵数目。
状态转移:
(u)上放置士兵,(u)的儿子们可放可不放。
[f(u,1)=1+sum_{j in Son(u)} min(f(j,0),f(j,1))
]
(u)上不放置士兵,(u)的儿子们必须放。
[f(u,0)=sum_{j in Son(u)} f(j,1)
]
const int N=1510;
vector<int> g[N];
int f[N][2];
int n;
void dfs(int u,int fa)
{
f[u][0]=0;
f[u][1]=1;
for(int i=0;i<g[u].size();i++)
{
int j=g[u][i];
if(j == fa) continue;
dfs(j,u);
f[u][0]+=f[j][1];
f[u][1]+=min(f[j][0],f[j][1]);
}
}
int main()
{
while(cin>>n && n)
{
for(int i=0;i<n;i++) g[i].clear();
for(int i=0;i<n;i++)
{
int id,m;
scanf("%d:(%d)",&id,&m);
while(m--)
{
int x;
scanf("%d",&x);
g[id].pb(x);
g[x].pb(id);
}
}
dfs(0,-1);
cout<<min(f[0][0],f[0][1])<<endl;
}
//system("pause");
return 0;
}