HDU4274 Spy's Work dfs搜索

给定一系列树形关系用来描述整个公司的人员关系,现在问给定的这些关系是否存在矛盾的地方。

比赛的时候写搓了,对于每一个点都去考虑的左右区间,其实这样做是不太好的,因为每次从员工推到boss,其实boss的工资是灵活变动的,也就是说只要boss工资的右区间减去所有孩子的左区间后还要至少留下单位1的工资来满足boss,所以只要计算一个区间关系即可,或者说,右区间是与孩子的右区间没有关系的。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define INF (1LL << 40)
#define MAXN 10000
using namespace std;

int N, head[MAXN+5], idx;

struct Node {
    long long l, r;
}e[MAXN+5];

struct Adj {
    int v, next;
}s[MAXN+5];

void init() {
    idx = -1;
    memset(head, 0xff, sizeof (head));    
}

void insert(int x, int v) {
    ++idx;
    s[idx].v = v, s[idx].next = head[x];
    head[x] = idx;
}

bool DFS(int x) {
    long long sum = 0;
    int v;
    for (int i = head[x]; i != -1; i = s[i].next) {
        v = s[i].v;
        if (!DFS(v)) {
            return false;    
        }
        sum += e[v].l;
    }
    e[x].l = max(e[x].l, sum + 1);
    return e[x].l <= e[x].r;
}

int main()
{
    int M, a, b, x;
    char op[5];
    bool ans;
    while (scanf("%d", &N) == 1) {
        ans = true;
        init();
        for (int i = 2; i <= N; ++i) {
            scanf("%d", &x);
            insert(x, i);
        }
        for (int i = 1; i <= N; ++i) {
            e[i].l = 1;
            e[i].r = INF;
        }
        scanf("%d", &M);
        for (int i = 0; i < M; ++i) {
            scanf("%d%s%d", &a, op, &b);
            if (op[0] == '=') {
                e[a].l = max(e[a].l, (long long)b);
                e[a].r = min(e[a].r, (long long)b); 
            } else if (op[0] == '<') {
                 e[a].r = min(e[a].r, (long long)(b-1));
            } else { 
                 e[a].l = max(e[a].l , (long long)(b+1));
            }
        }
        puts(DFS(1) ? "True" : "Lie");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Lyush/p/2679405.html