题意:
我们派出的间谍得到一些信息,信息包括N个职工分别负责N个部门,每个职工最多有一个上司,每个职工的工资最少为1,上司i负责部门i 而i的下属也属于部门i,给出m个部门的描述,
i < W 表示部门i的所有人的总工资小于w,(包括i以及i的下属,下边一样);
i > W 表示部门i的所有人的总工资大于W;
i = W 表示部门i所有人的总工资等于W
让你判断这些信息是否正确,如果寻在矛盾说明不正确。
分析:
很明显的是一颗树状结构。每个节点表示一个部门。维护一个low[u],up[u],表示该部分工资的范围,闭区间。这样,如果不矛盾,由孩子节点来更新根节点。DFS一遍,回溯即可。
Mark:这个题目应该是最简单的一题了,跪烂。写复杂了,不知道怎么错的。最后重新写一遍就过了。囧。
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #define N 10010 5 6 struct edge{ 7 int v; 8 int next; 9 }e[N]; 10 int last[N]; 11 int tot; 12 13 void add(int u,int v){ 14 e[tot].v = v; 15 e[tot].next = last[u]; 16 last[u] = tot++; 17 return ; 18 } 19 int n; 20 int m; 21 int low[N]; 22 int up[N]; 23 int max(int x,int y) 24 { 25 return x>y?x:y; 26 } 27 bool dfs(int u){ 28 int sum = 0; 29 30 for (int j=last[u];j!=-1;j=e[j].next){ 31 int v = e[j].v; 32 if (!dfs(v)) 33 return false; 34 sum += low[v]; 35 } 36 low[u] = max(low[u] , sum + 1); 37 if (up[u]!=-1 && up[u]<low[u]) 38 return false; 39 return true; 40 } 41 int main() 42 { 43 int u,val; 44 char str[5]; 45 46 while (scanf("%d",&n)==1){ 47 memset(low,-1,sizeof(low)); 48 memset(up,-1,sizeof(up)); 49 50 memset(last,-1,sizeof(last)); 51 tot = 0; 52 for (int i=2;i<=n;i++) 53 { 54 scanf("%d",&u); 55 add(u,i); 56 } 57 scanf("%d",&m); 58 while (m--){ 59 scanf("%d%s%d",&u,str,&val); 60 if (str[0] == '='){ 61 low[u] = up[u] = val; 62 }else if (str[0] == '<'){ 63 up[u] = val-1; 64 }else{ 65 low[u] = val+1; 66 } 67 } 68 if (dfs(1)) 69 puts("True"); 70 else 71 puts("Lie"); 72 } 73 return 0; 74 }