zoukankan      html  css  js  c++  java
  • Codeforces 486D Valid Sets (树型DP)

    题目链接 Valid Sets

    题目要求我们在一棵树上计符合条件的连通块的个数。

    满足该连通块内,点的权值极差小于等于d

    树的点数满足 n <= 2000

    首先我们先不管这个限制条件,也就是先考虑d为正无穷大的时候的情况。

    我们要求出树上所有连通块的个数。

    这个时候我们令f[i]为以i为根的子树中的连通块的数目。

    此时状态转移方程为 f[x] = f[x] * (f[u] + 1)

    其中f[x]初始值为1,u为x的儿子

    最后f[1]的值(我们假设1为根结点)即为答案

    时间复杂度为O(n)

    注意到n只有2000,说明这题的时间复杂度不止O(n)

    那么我们对于每一个点,以他的权值作为连通块的权值最小值。

    于是就可以以他为根做一次DFS。

    若DFS的过程中碰到权值比他小的点,或者权值减他的权值大于d的点,我们就不往这个点DFS下去。

    但是有一种特殊情况

    这样做可能导致重复计算

    因为这样的方法会导致两个权值相同切且相连的点组成的连通块被计算多次。

    于是我们对那些权值相同切且相连的点的边,定一个方向。

    规定编号小的点能DFS到编号大,和他相连且权值和他相等的点

    但是反过来就不行了。

    这样规定了一个方向之后我们就消除了重复计算的问题。

    时间复杂度 $O(n^{2})$

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    typedef long long LL;
    
    const int N = 2010;
    const LL mod = 1e9 + 7;
    
    vector <int> v[N];
    int n, d, et, cnt;
    int a[N];
    LL f[N];
    LL ans = 0;
    
    void dfs(int x, int fa){
    	LL now = 0;
    	f[x] = 1;
    	for (auto u : v[x]){
    		if (u == fa) continue;
    		if (a[u] > cnt + d || a[u] < cnt) continue;
    		if (a[u] == cnt && u < et) continue;
    		dfs(u, x);
    		(f[x] *= f[u] + 1) %= mod;
    	}
    }
    
    	
    
    int main(){
    
    	scanf("%d%d", &d, &n);
    	rep(i, 1, n) scanf("%d", a + i);
    	rep(i, 1, n - 1){
    		int x, y;
    		scanf("%d%d", &x, &y);
    		v[x].push_back(y);
    		v[y].push_back(x);
    	}
    
    	rep(i, 1, n){
    		cnt = a[i]; et = i;
    		memset(f, 0, sizeof f);
    		dfs(i, 0);
    		(ans += f[i]) %= mod;
    	}
    
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    asp.net正则匹配嵌套Html标签
    sql语句插入百万测试数据
    js判断网页是真静态还是伪静态的方法
    sql自动创建表并复制数据
    百度地图API-搜索地址、定位、点击获取经纬度并标注
    kindeditor自定义插件插入视频代码
    mongo 取随机100条数据写入Excel
    python实现RSA加密和签名以及分段加解密的方案
    装饰器写法
    大转盘抽奖概率 固定每个区域的中奖几率
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7418797.html
Copyright © 2011-2022 走看看