hdu 4274

其实这题挺水的,当时就老往并查集上想,搞得昏天暗地的。

#include<stdio.h>
#include<vector>
#include<string.h>
#define LL long long
#define INF (1<<31-1)
using namespace std;
vector<int> son[10010];
int L[10010],R[10010];  int ans; int sum[10010];

void initial(int n)
{
    int i;
    for(i=0;i<=n;i++)
        son[i].clear(),R[i]=INF;
    memset(L,0,sizeof(L));
    memset(sum,0,sizeof(sum));
}

void dfs(int u)
{
    if( ans==0 ) return;
    int len,i; LL l,r; l=0;r=0;
    len= son[u].size();
    sum[u]=1;
    for(i=0;i<len;i++)
    {
        dfs(son[u][i]);  if( ans==0 ) return;
        sum[u]+=sum[son[u][i]];
        l+=L[son[u][i]];
        r+=R[son[u][i]];
    }
    if( len==0 )
    {
        sum[u]=1;
        if ( R[u] < sum[u]) ans=0;
        else
            if( L[u] < sum[u] ) L[u]=sum[u];
    }
    else
    {
        if( r < sum[u]-1 || R[u] < sum[u]) ans=0;
        else
            if( R[u]<=l ) ans=0;
            else
                if( L[u]<l+1) L[u]=l+1;
    }
}

int main()
{
    int i,j,x,n,m,k;  int a,b; char ch;
    while(scanf("%d",&n)!=EOF)
    {
        initial(n); ans=1;
        for(i=2;i<=n;i++)
        {
            scanf("%d",&x);
            son[x].push_back(i);
        }
        scanf("%d",&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d %c %d",&a,&ch,&b);
            if( ch=='<')
            {
                if( b > L[a])
                    if( b-1 < R[a] ) R[a]=b-1; else {}
                else  ans=0;
            }
            else
                if( ch=='>')
                {
                    if( b >= R[a] )
                        ans=0;
                    else
                        if( b+1 > L[a])  L[a]=b+1;
                }
                else
                    if( b>=L[a] && b<=R[a] ) L[a]=R[a]=b;
                    else ans=0;
        }
        dfs(1);
        if( !ans ) printf("Lie\n");
        else printf("True\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值