您的位置:首页 > 其它

HDU 4274 - Spy's Work(树形DP)

2015-09-03 16:47 337 查看
题目:

http://acm.hdu.edu.cn/showproblem.php?pid=4274

题意:

给出n个点的树,树上的节点权值为其子树的节点权值和(大于等于1),给出一些节点的限制条件,判断这些条件是否成立。

思路:

midp:表示该节点权值的下限,madp:表示该节点权值的上限。

按照题目所给的限制条件,赋值dp数组。

在dfs中更新 midp,节点的权值上限无法确定,判断midp<=madp 是否成立。

AC.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long long ll;
const ll inf = 1e17+5;
const int maxn = 10005;
int n;

int tol, head[maxn];
struct Edge{
int to, next;
}edge[maxn];
void addedge(int u, int v)
{
edge[tol].to = v;
edge[tol].next = head[u];
head[u] = tol++;
}

ll midp[maxn], madp[maxn];
ll son[maxn];
bool dfs(int u)
{
ll mins = 1;
son[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;

bool flag = dfs(v);
if(flag) {
son[u] += son[v];
mins += midp[v];
}
else return false;
}

midp[u] = max(mins, midp[u]);
return midp[u] <= madp[u];
}

void init()
{
tol = 0;
memset(head, -1, sizeof(head));
for(int i = 1; i <= n; ++i) {
midp[i] = 1;
madp[i] = inf;
}
}
int main()
{
// freopen("in", "r", stdin);
while(~scanf("%d", &n)) {
int u;
init();
for(int v = 2; v <= n; ++v) {
scanf("%d", &u);
addedge(u, v);
}

int m;
scanf("%d", &m);
for(int i = 0; i < m; ++i) {
int vl;
char ch;
scanf("%d %c %d", &u, &ch, &vl);
if(ch == '=') {
midp[u] = max(midp[u], (ll)vl);
madp[u] = min(madp[u], (ll)vl);
}
if(ch == '>') {
midp[u] = max(midp[u], (ll)vl+1);
}
if(ch == '<') {
madp[u] = min(madp[u], (ll)vl-1);
}
}

// for(int i = 1; i <= n; ++i) {
// printf("i =%d: (%lld, %lld)\n", i, midp[i], madp[i]);
// }

if(dfs(1)) {
printf("True\n");
}
else printf("Lie\n");
}
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU