zoukankan      html  css  js  c++  java
  • CodeForces 486D.Valid Sets(树形DP)

    题意:给出一个n个节点的连通图,问有多少个子集,使得子集中节点的最大值减最小值的差值不大于d。子集不得为空,子集需要是一个连通图。

    分析:第一行d,n。((0 <= d <= 2000, 1 <= n <= 2000))。第二行n个数字ai表示每个节点的权值((1 <= ai <= 2000)。)我们可以看出这个不是图,是一棵树,是树,说明可以用树形DP等方式计数,我们用dfs跑每个点作为最大值时的连通图,如果这个联通图中最大值和最小值<=d,说明可以统计起来,即(res = res + res * dfs(j, u))。可以看如下的图,每次循环就加上右边乘以左边的,我们还需要防止重复的计数,即如果一个节点和最大值相同的话,我们需要从大的节点编号走到小的节点编号,可以防止重复计数。

    //这个计数方式非常经典,可以记录一下。(点分治的一种算法就采用这种做法)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    using LL = long long;
    const int N = 2005;
    const int mod = 1e9 + 7;
    int a[N];
    int h[N], e[N * 2], ne[N * 2], idx;
    void add(int a, int b)
    {
    	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    
    int root, val;
    int d, n;
    
    int dfs(int u, int fa)
    {
    	int res = 1;
    	for (int i = h[u]; i != -1; i = ne[i])
    	{
    		int j = e[i];
    		if (j == fa) continue;
    		if ((val > a[j] && val - a[j] <= d) || (val == a[j] && j < root))
    		{
    			res = (res + ((LL)res * dfs(j, u)) % mod) % mod;
    		}
    	}
    	return res;
    }
    
    int main()
    {		
    	scanf("%d%d", &d, &n);
    
    	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    
    	memset(h, -1, sizeof h);
    	int u, v;
    	for (int i = 1; i < n; ++i)
    	{
    		scanf("%d%d", &u, &v);
    		add(u, v), add(v, u);
    	}
    
    	int res = 0;
    	for (int i = 1; i <= n; ++i)
    	{
    		root = i, val = a[i];
    		res = (res + dfs(i, -1)) % mod;
    	}
    
    	printf("%d
    ", res);
    
    	return 0;
    }
    
  • 相关阅读:
    CodeForces 347B Fixed Points (水题)
    CodeForces 347A Difference Row (水题)
    CodeForces 346A Alice and Bob (数学最大公约数)
    CodeForces 474C Captain Marmot (数学,旋转,暴力)
    CodeForces 474B Worms (水题,二分)
    CodeForces 474A Keyboard (水题)
    压力测试学习(一)
    算法学习(一)五个常用算法概念了解
    C#语言规范
    异常System.Threading.Thread.AbortInternal
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13321463.html
Copyright © 2011-2022 走看看