zoukankan      html  css  js  c++  java
  • hdu7115 Vertex Deletion

    https://acm.hdu.edu.cn/showproblem.php?pid=7115

    题意:

    一棵树,删点。要求不能删出孤立的点。问有多少种删除的方案。

    一道挺简单的树形dp,可惜比赛的时候没看这个题

    f[i][0]表示i的子树中,点i删除的方案数。要求i的剩余子树是合法的删点。

    f[i][1]表示i的子树中,点i没有删除,i的直接子节点全删除了。这个状态的i虽然暂时是孤立的,但是还有i的父节点。它的存在说明如果要使用这个状态,父节点不可以删除。

    f[i][2]表示i的子树中,点i没有删除,i的直接子节点还有没删除的。要求i的剩余子树是合法的删点。

    为什么这么定义状态?

    至少我们要表示出点i的子树中,i有没有删除这两种状态

    若没有删除点i,如果i的直接子节点全删除了,要求i的父节点不能删除;如果i的直接子节点还有没删除的,父节点随意

    若删除了点i,要求i的直接子节点还有子节点没有删除

    理清了这个,转移方程也出来了

    f[i][0] = Π(f[t][0]+f[t][2]) ,点i删除了,那么i的直接子节点不能成为孤立的点。

    f[i][1] = Πf[t][0],点i没有删除,同时要求删除i的全部直接子节点。

    f[i][2] = Π(f[t][0]+f[t][1]+f[t][2]) - f[i][1],点i没有删除,还与直接子节点相连的方案数,用子节点的全部情况减去子节点全删除的方案数

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 100003
    
    int front[N],to[N<<1],nxt[N<<1],tot; 
    int f[N][3];
    
    const int mod=998244353;
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
    }
    
    void dfs(int x,int fa)
    {
        int t;
        f[x][0]=1;
        f[x][1]=1;
        f[x][2]=1;
        for(int i=front[x];i;i=nxt[i])
        {
            t=to[i];
            if(t==fa) continue;
            dfs(t,x);
            f[x][0]=1ll*f[x][0]*(f[t][0]+f[t][2])%mod;
            f[x][1]=1ll*f[x][1]*f[t][0]%mod;
            f[x][2]=1ll*f[x][2]*((f[t][0]+f[t][1])%mod+f[t][2])%mod;
        }
        f[x][2]=(f[x][2]-f[x][1]+mod)%mod;
    }
    
    int main()
    {
        int T,n,u,v;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            tot=0;
            for(int i=1;i<=n;++i) front[i]=0;
            for(int i=1;i<n;++i) 
            {
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            dfs(1,0);
            printf("%d
    ",(f[1][0]+f[1][2])%mod);
        }
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    write to logfile
    open and read a file content to a variable
    strategy
    Android 开机启动程序
    消息队列
    卡机音乐功能实现
    Android 2.0 开机动画文件分析
    多线程实例
    消息队列
    多线程实例
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15229478.html
Copyright © 2011-2022 走看看