很简单的题目。一开始看错题目了,误以为每个士兵可以守住相邻的节点,将状态方程改了之后,分别记录当前节点派不派士兵的最优值。
ACcode:
#include<cstdio>
#include<cstring>
const int nsize=15555;
int n,p,s,k,d0,d1;
bool v[nsize];
int head[nsize],next[nsize<<1],e[nsize<<1],top;
int Min(int a1,int a2)
{
return a1<a2?a1:a2;
}
void add(int u,int v,int i)
{
next[i]=head[u];
e[i]=v;
head[u]=i;
}
void dfs(int rt)
{
int a0,a1;
v[rt]=a0=a1=0;
for (int i=head[rt];i!=-1;i=next[i])
{
if (v[e[i]])
{
dfs(e[i]);
a0+=d1;
a1+=Min(d0,d1);
}
}
d0=a0,d1=a1+1;
// printf("rt=%d %d %d\n",rt,d0,d1);
}
int main()
{
while (~scanf("%d",&n))
{
top=0;
for (int i=0;i<n;i++) head[i]=-1,v[i]=true;
for (int i=0;i<n;i++)
{
scanf("%d:(%d)",&p,&k);
for (int j=0;j<k;j++)
{
scanf("%d",&s);
add(p,s,top++);
add(s,p,top++);
}
}
dfs(0);
printf("%d\n",d0<d1?d0:d1);
}
return 0;
}