CodeChef - CHEFPRAD Chef and Pairs 树形DP
题意
给你一棵由 N 个节点构成的树 T。节点按照 1 到 N 编号,每个节点要么是白色,要么是黑色。有 Q 组询问,每组询问形如 (s, b)。你需要检查是否存在一个连通子图,其大小恰好是 s,并且包含恰好 b 个黑色节点。
数据
输入第一行,包含一个整数 T,表示测试数据组数。对于每组测试数据:
第一行包含两个整数 N 和 Q,分别表示树的节点个数和询问个数。
接下来 N - 1 行,每行包含两个整数 ui 和 vi,表示在树中 ui 和 vi 之间存在一条边。
接下来一行包含 N 个整数,c1, c2, ... , cN。如果 ci 为 0 表示第 i 个节点是白色的,如果 ci 为
1 表示第 i 个节点是黑色的。
接下来 Q 行,每行包含两个整数 si 和 bi,表示一组形如 (si, bi) 的询问。
对于每组询问输出一行字符串表示答案,其中 Yes 表示存在一个符合要求的连
通子图,No 表示不存在。
1 <= T <= 5, 2 <= N <= 5e3, 1 <= Q <= 1e5, 1 <= ui, vi <= N。
0 <= ci <= 1, 0 <= bi <= N, 1 <= si <= N, bi <= si。
输入
1
9 4
4 1
1 5
1 2
3 2
3 6
6 7
6 8
9 6
0 1 0 1 0 0 1 0 1
3 2
7 3
4 0
9 5
输出
Yes
Yes
No
No
说明
对于第一组询问,包含由 {6, 7, 9} 构成的连通子图,其中恰包含两个黑色节点 7 和 9。
对于第二组询问,包含由 {1, 2, 3, 4, 6, 7, 8} 构成的连通子图,其中恰包含三个黑色节点 2,4和 7。
对于第三组询问和第四组询问,均不存在符合要求的连通子图。
题解:
观察到一个现象,对于一个子树,在子树中子图的点数确定的情况下,可行的黑点数是一个连续的区间。
那么很自然地用f[i][j]记下在子树i中用了j个点的情况下最多和最少的黑点数,背包一下就可以了。
剩下一个问题,就是复杂度。你会发现每个点对在dp的过程中都只出现一次,所以复杂度是n^2的。
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e3+, M = 1e3+, mod = 1e9+,inf = 2e9; int f[N][N][],mi[N],mx[N],c[N],siz[N];
int head[N*],t = ;
struct ss{
int next,to;
}e[N * ];
int T,Q,n;
inline void add(int u,int v) {
e[t].to = v;
e[t].next = head[u];
head[u] = t++;
}
void dfs(int u,int fa) {
siz[u] = ;
if(c[u])f[u][][] = f[u][][] = ;
else f[u][][] = f[u][][] = ;
for(int i = head[u]; i; i = e[i].next){
int to = e[i].to;
if(to == fa) continue;
dfs(to,u);
for(int k = siz[u]; k >= ; --k){
for(int j = ; j <= siz[to]; ++j) {
f[u][k+j][] = min(f[u][k+j][],f[u][k][] + f[to][j][]);
f[u][k+j][] = max(f[u][k+j][],f[u][k][] + f[to][j][]);
}
}
siz[u] += siz[to];
}
for(int j = ; j <= siz[u]; ++j)
mi[j] = min(mi[j],f[u][j][]),mx[j] = max(mx[j],f[u][j][]);
}
int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&Q); memset(head,,sizeof(head));
t = ; for(int i = ; i <= n; ++i) mi[i] = inf,mx[i] = ; for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) f[i][j][] = inf,f[i][j][] = ; for(int i = ; i < n; ++i) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
} for(int i = ; i <= n; ++i) scanf("%d",&c[i]); dfs(,); while(Q--) {
int x,y;
scanf("%d%d",&x,&y);
if(mi[x] <= y && mx[x] >= y) {
printf("Yes\n");
}
else printf("No\n");
} }
return ;
}
CodeChef - CHEFPRAD Chef and Pairs 树形DP的更多相关文章
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
- poj3162(树形dp+优先队列)
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 5409 Accepted: 1371 Ca ...
- POJ 3162.Walking Race 树形dp 树的直径
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 4123 Accepted: 1029 Ca ...
- POJ-3659-最小支配集裸题/树形dp
Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7127 Accepted: 254 ...
- 【bzoj2591】[Usaco 2012 Feb]Nearby Cows 树形dp
题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...
- 树的直径的求法即相关证明【树形DP || DFS】
学习大佬:树的直径求法及证明 树的直径 定义: 一棵树的直径就是这棵树上存在的最长路径. 给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间的距 ...
- codeforces766E Mahmoud and a xor trip(按位统计+树形DP)
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- Choosing Capital for Treeland CodeForces - 219D (树形DP)
传送门 The country Treeland consists of n cities, some pairs of them are connected with unidirectional ...
- CF 219 D:Choosing Capital for Treeland(树形dp)
D. Choosing Capital for Treeland 链接:http://codeforces.com/problemset/problem/219/D The country Tre ...
随机推荐
- java线程总结--synchronized关键字,原理以及相关的锁
在多线程编程中,synchronized关键字非常常见,当我们需要进行“同步”操作时,我们很多时候需要该该关键字对代码块或者方法进行锁定.被synchronized锁定的代码块,只能同时有一条线程访问 ...
- 【HDU 6005】Pandaland(Dijkstra)
Problem Description Mr. Panda lives in Pandaland. There are many cities in Pandaland. Each city can ...
- JavaScript中离线应用和客户端存储(cookies、sessionStorage、localStorage)
一.离线应用 所谓离线web应用,就是在设备不能上网的情况下仍然可以运行的应用. 开发离线web应用需要几个步骤:首先,确保应用知道设备是否能上网,以便下一步执行正确的操作:然后,应用还必须能访问一定 ...
- 【02】使用Firebug查看和编辑HTML和CSS
使用Firebug查看和编辑HTML和CSS 描述 在本章节的教程中,我们将讨论如何使用Firebug查看和编辑HTML和CSS. 使用Firebug查看和编辑HTML 在你要查看的元素上右击鼠标然后 ...
- 大数据学习——mapreduce共同好友
数据 commonfriends.txt A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D ...
- Python和Mongodb
定义好链接DB类 # -*- coding: UTF-8 -*- from pymongo import MongoClient # 数据库连接 class MongoDB(object): def ...
- POJ 1273 Drainage Ditches【图论,网络流】
就是普通的网络流问题,想试试新学的dinic算法,这个算法暑假就开始看国家集训队论文了,之前一直都只用没效率的EK算法,真正学会这个算法还是开学后白书上的描述:dinic算法就是不断用BFS构建层次图 ...
- POJ 2420 A Star not a Tree?【爬山法】
题目大意:在二维平面上找出一个点,使它到所有给定点的距离和最小,距离定义为欧氏距离,求这个最小的距离和是多少(结果需要四舍五入)? 思路:如果不能加点,问所有点距离和的最小值那就是经典的MST,如果只 ...
- 会修修的莫队--BZOJ2120: 数颜色
$n \leq 10000$的数列,$m \leq 10000$个操作,一:单点修改:二:查区间不同数字个数.修改数$\leq 1000$,数字$\leq 1000000$. 我不会告诉您这是三种写法 ...
- 汕头市赛srm10 T2
n个数,分组,数Ai要在至少含有Ai个数的组,求最多分多少组. 方法一:大的数应该尽量跟大的在一起,这样才能让小的出现很多很多组,所以从大到小排序,给当前序列中最大的数x分x个数.代码如下: #inc ...