梦,才是最真的现实

导航

HDU 4274 spy work (树形DP)

相对水的一道树形DP,把父子关系想清楚了就容易多了

题意:给出一部分节点的信息,问你这部分信息有没有冲突。大致题意。详细自己看。

解题思路:我的想法是给通过两个数组表示各个节点的上下限,如果上限小于下限,那么这是冲突的,上限==下限,表明这点的工资是确定的。

                     先输入各种关系,然后一遍DFS即可。我们得明白一件事,儿子只能够修改父亲的下限,不能修改父亲的上限

#include<iostream>
#include<stdio.h>
#include<string.h>
#define LL long long 
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int maxn=10005;
struct edge
{
    int u,v,next;
}e[maxn<<1];
int tot,head[maxn],n,m;
LL upper[maxn],lower[maxn];
bool vis[maxn],conflict;
void add_edge(int u,int v);
void dfs(int root);
int main()
{
    int a,i,b;
    LL B;
    char re;
    while(cin>>n)
    {
        memset(head,-1,sizeof(head));
        tot=0;
        for(i = 2;i <= n; i++)
        {
            a=i;
            cin >> b;
            add_edge(a,b);
            add_edge(b,a);
        }
        memset(upper,-1,sizeof(upper));//上限为-1,表示不确定
        for(i=1;i<=n;i++)
            lower[i]=1;
        cin >> m;
        for(i = 1;i <= m; i++)
        {
            scanf("%d %c %lld",&a,&re,&B);
            if(re == '=') upper[a]=lower[a]=B;
            else if(re == '>') lower[a]=B+1;
            else upper[a]=B-1;
        }
        conflict=false;
        memset(vis,false,sizeof(vis));
        dfs(1);
        if(conflict)
            puts("Lie");
        else puts("True");
    }
    return 0;
}
void add_edge(int u,int v)
{
    e[tot].u=u,e[tot].v=v;
    e[tot].next=head[u],head[u]=tot++;
}
void dfs(int root)
{
    if(vis[root]||conflict) return ;
    vis[root] = true;
    if(upper[root]!=-1&&upper[root]<lower[root]) //先判断每个节点自身是否有矛盾
    {
        conflict=true;
        return ;
    }
    int i,nexti;
    LL lo;
    bool leaf=true;
    lo=0;
    for(i=head[root];i!=-1;i=e[i].next)
    {
        nexti=e[i].v;
        if(!vis[nexti])
        {
            leaf=false;
            dfs(nexti);
            lo+=lower[nexti];//统计儿子下限 
        }
    }
    if(leaf) return ;
    lo++;
    lower[root]=max(lo,lower[root]);//更新父亲的下限
    if(upper[root]!=-1&&lower[root]>upper[root])//检测冲突
    {
        conflict=true;
    }
}


posted on 2012-09-11 10:32  梦,才是最真的现实  阅读(190)  评论(0编辑  收藏  举报