zoukankan      html  css  js  c++  java
  • 树形dp

    树形dp

    题号:Codeforces 461B

    题意:

    输入 n ,表示有一个 n 个节点的树;

    输入 n-1 个数 P[0] ~ P[n-1],p[i]表示无向边将 i+1 和 P[i] 连接起来

    输入 n 个数 ,表示每个节点的颜色,0为白色,1为黑色

    要切断 k 条边变成 k 个连通分量,每个分量有且只有一个方案数,求有多少种分割方案;

    思路:

    从根节点向下递归,上层利用回溯计算结果;

    实在搞不懂,先记录一下

    撸代码:

     1#include<stdio.h>
    2#include<string.h>
    3#define N 101000
    4struct Edge
    5{

    6    int to,nex;
    7} edge[N*3];
    8int cnt,n;
    9int head[N];/**链表头结点*/
    10int c[N];/**标记节点黑白*/
    11long long dp[N][2];
    12void init()
    13
    {
    14    memset(head,-1,sizeof(head));
    15    cnt=0;
    16}
    17
    18void addEdge(int u,int v)
    19
    {
    20    edge[cnt].to=v;
    21    edge[cnt].nex=head[u];
    22    head[u]=cnt++;
    23
    24    edge[cnt].to=u;
    25    edge[cnt].nex=head[v];
    26    head[v]=cnt++;
    27
    28}
    29long long mod=1000000007;
    30void dfs(int u,int fa)
    31
    {
    32
    33    dp[u][c[u]]=1;
    34    for(int i=head[u]; i!=-1; i=edge[i].nex)
    35    {
    36        int v=edge[i].to;
    37        if(v==fa)
    38            continue;
    39        dfs(v,u);/**从上往下遍历 ,利用回溯*/
    40
    41        /**dp 数组含义:以U为根,当前连通块有黑点 [1] 或没有黑点 [0] 方案数*/
    42
    43        /**子树和根都有黑点,则边剪掉;根为黑点但子树无黑点,保留边;根无黑点而子树有黑点*/
    44        dp[u][1]=(dp[u][1]*dp[v][1]%mod+dp[u][0]*dp[v][1]%mod+dp[u][1]*dp[v][0]%mod)%mod;
    45
    46        /**没有黑点就要保留所有*/
    47        dp[u][0]=(dp[u][0]*dp[v][0]%mod+dp[u][0]*dp[v][1]%mod)%mod;
    48    }
    49
    50}
    51
    52int main()
    53
    {
    54
    55    scanf("%d",&n);
    56    init();
    57    int v;
    58    for(int i=1; i<n; i++)
    59    {
    60        scanf("%d",&v);
    61        addEdge(v,i);
    62    }
    63
    64    for(int i=0; i<n; i++)
    65    {
    66        scanf("%d",&c[i]);
    67    }
    68    dfs(0,0);
    69    printf("begin: ");
    70    for(int i=0;i<n;i++)
    71    {
    72        printf("i=%d : %lld %lld ",i,dp[i][0],dp[i][1]);
    73    }
    74    printf("%lld ",dp[0][1]);
    75    return 0;
    76}
  • 相关阅读:
    Linux-文件编程
    Linux-编程基础
    Linux-系统管理
    Linux-命令
    图解HTTP-笔记
    微信小程序发送红包功能。填坑记录
    PHP中使用raw格式发送POST请求
    论一个PHP项目上线的注意点
    PHP CURL 模拟form表单上传遇到的小坑
    使用php的curl函数post返回值为301永久迁移的问题。(301 Moved Permanently)
  • 原文地址:https://www.cnblogs.com/HappyKnockOnCode/p/12853078.html
Copyright © 2011-2022 走看看