題意:一個結構像一棵樹一樣的公司。一個間諜去打探,然後發回來一些訊息,讓我們判斷真假。
做法:這些訊息裡只要有一條不對,這個間諜就在撒謊。 不對的情況是最終的上界小於下界,或者結合資訊做出來的某個節點不合理。
#include <cstdio>#include <cstring>#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))typedef __int64 LL;#define inf 1e15; const int LMT = 10002;LL __up[LMT], __down[LMT], ori_down[LMT];int next[LMT], all;struct __line{ int u, v, next;}e[LMT << 1];void init(void){ memset(next, -1, sizeof(next)); memset(ori_down, 0, sizeof(ori_down)); for(int i = 0; i < LMT; ++i) { __up[i] = inf; __down[i] = 1; } all = 0;}void insert(int u, int v){ e[all].u = u; e[all].v = v; e[all].next = next[u]; next[u] = all++;}void dfs(int u, int pre){ int v, x; for(x = next[u]; x != -1; x = e[x].next) if(e[x].v != pre) { v = e[x].v; dfs(v, u); ori_down[u] += max(ori_down[v], __down[v]); } ++ori_down[u];}int main(void){ int n, i , j, m; char tag; while(~scanf("%d", &n)) { init(); for(j = 2; j <= n; ++j) { scanf("%d", &i); insert(i, j); insert(j, i); } scanf("%d", &m); while(m--) { scanf("%d %c %d", &i, &tag, &j); switch(tag) { case '>':__down[i] = max(__down[i], j + 1); break; case '<':__up[i] = min(__up[i], j - 1); break; case '=': __down[i] = max(__down[i], j); __up[i] = min(__up[i], j); break; } } dfs(1, -1); for(i = 1; i <= n; ++i) if(__up[i] < __down[i] || ori_down[i] > __up[i]) { printf("Lie\n"); break; } if(i > n)printf("True\n"); } return 0;}