很多人说这个是个树形dp,我觉得不算吧,对于每个节点它的左右子树的权值和的范围是已知的,而这个节点本身的取值是[1,inf)所以区间加法即可得到以这个点为根节点的树的所有节点权值和的范围,与题目中的范围作比较,若存在交集则说明存在解,更新这个树的权值和的范围即可,否则说明无解,因为每个节点本身的取值都是没有上界的所以区间加法时不需要考虑上界
#include <cstdio>
#include <cstring>
struct point
{
int end,next;
}s[10010];
int begin[10010],n,q,f[10010],g[10010],i,j,k,x,m,a,b,inf;
char ss[10];
bool ans;
void dfs(int u,int &x)
{
int i,v,c;
x=1;
for(i=begin[u];i!=-1;i=s[i].next)
{
v=s[i].end;
dfs(v,c);
x+=c;
}
if(f[u]>x)x=f[u];
if(x>g[u])ans=0;
}
int main()
{
while(scanf("%d",&n)==1)
{
k=0;
memset(begin,-1,sizeof(begin));
for(i=2;i<=n;i++)
{
scanf("%d",&x);
s[k].end=i;
s[k].next=begin[x];
begin[x]=k;
k++;
}
scanf("%d",&m);
memset(f,0,sizeof(f));
memset(g,127,sizeof(g));
inf=g[0];
while(m--)
{
scanf("%d%s%d",&a,ss,&b);
if(ss[0]=='>')f[a]=b+1;
else if(ss[0]=='=')f[a]=g[a]=b;
else g[a]=b-1;
}
ans=1;
dfs(1,a);
if(ans)puts("True");
else puts("Lie");
}
return 0;
}