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;
}
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 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 1000
- HDU 1001
- hdu-5385
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- Hdu5033
- HDU 1166 敌兵布阵
- HDU Rightmost Digit
- hdu 1002
- 贪心 hdu 1003