2019 湖南省赛 I题 2019 (树形DP???)

题目链接
当时比赛的时候没有写出来,当时,换根DP不太熟练,所以没怎么,往那方面去想,想了一个类似树形DP,结果还是没写出来。
然后,仔细学了会换根DP,后面的沈阳网络赛就碰到一道换根DP的题,喜提一发PE AC
但是,还是想用自己最初的那个想法去做,并且A掉
牛客网1号就能开了省赛的复现赛 (????),国庆嘛,太高兴了,然后到今天才去写,啦啦啦啦

想法:
在这里插入图片描述
如上图,红色表示树的组成部分,蓝色表示路径的种类
在一棵子树中,将路径分为三种:
(1) 只有一条边
(2) 子树的根节点是路径的端点(至少由两条边组成)
(3) 子树的根节点不是路径的端点,(至少由两条边组成)
对于三种路径的答案的统计的方法:
令根节点是u, u的一个子节点是v, val 是边(u, v)的权值
(1) 在输入的时候,直接判断下就好了
(2) 就是节点v 所控制的子树中,能与val组成符合答案的个数
(3) 如图上的(3) 就是dp[5][3]*dp[6][2017]
代码中会有详细的注释

#include <bits/stdc++.h>
const int maxn = 2e4+50;
const int maxm = 2020;
using namespace std;
typedef long long ll;
struct note{
    int to, w;
    note(){}
    note(int to1, int w1){
        to = to1, w = w1;
    }
};
vector <note> maps[maxn];
int  n, in[maxn];
ll ans, dp[maxn][maxm], tmp[maxm];
// dp[u][i] 表示节点u控制的子树中,以u为端点的路径,值为i的种类数


void dfs(int u, int fa, int val){
    //u dfs的当前节点, fa  节点u的父节点   val  边(u, fa)的权值
    for(int i=0; i<2019; i++)       //初始化
        dp[u][i] = 0;
    for(int i=0, len=maps[u].size(); i<len; i++){
        int v = maps[u][i].to, w = maps[u][i].w;
        if(v != fa){
            dfs(v, u, w);
            for(int j=0; j<2019; j++){
                ans += dp[u][j]*dp[v][(2019-j)%2019];   //由(3)产生的答案数
                dp[u][j] += dp[v][j];   //把子树的统计结果累加上去
            }
        }
    }
    if(in[u] != 1 && u != fa)
        ans += dp[u][(2019-val)%2019];  //由(2)产生的答案数,但是不能统计叶子节点和整棵树的根节点
    for(int i=0; i<2019; i++)
        tmp[(i+val)%2019] = dp[u][i];
    for(int i=0; i<2019; i++)
        dp[u][i] = tmp[i];  
    dp[u][val%2019]++;
}

int main()
{
    while(scanf("%d", &n)!=EOF){
        ans = 0;
        for(int i=0; i<=n; i++)
            maps[i].clear(), in[i] = 0;
        for(int i=1, a, b, c; i<n; i++){
            scanf("%d%d%d", &a, &b, &c);
            maps[a].push_back(note(b, c));
            maps[b].push_back(note(a, c));
            in[a]++, in[b]++;
            if(c%2019 == 0)
                ans++;      //由(1)产生的答案数
        }
        dfs(1, 1, 2019);
        printf("%lld\n", ans);
    }
    return 0;
}

不懂的,可以和我交流

posted @ 2019-10-08 17:18  季之怡  阅读(36)  评论(0编辑  收藏  举报