zoukankan      html  css  js  c++  java
  • Codeforces Round #630 (Div. 2) F. Independent Set (树型dp)

    https://codeforces.com/contest/1332/problem/F

    题中描述是一棵树,给出树上子图存在独立点集的定义:G‘为全图G的子图,G‘在存在点对(u,v),E(u,v)不存在。现求G中有多少个子图可以满足存在独立点集?求所有的方案数。

    题目抽象为:在树中的子树中选出一些点,它们互相之间不存在直接的连边,求这样的点集方案数。考虑树型dp做法。设计状态dp[u][0]表示当前结点u不作为独立点的方案数,dp[u][1]表示当前结点u作为独立点的方案数。

    假设不考虑子图,那么dp[u][0] = ∏ dp[v][0] + dp[v][1],dp[u][1] = ∏ dp[v][0],这是一个很显然的树型dp转移方程,其中v是u的儿子结点。

    由于题中说明是求子图的方案数,那么还需要考虑u和v不连边的情况了。当u和v不连边去构成独立子图时,任何的结点x不能单独作为孤立的独立点存在,也就是说x如果作为独立点,不和任何结点连边是不合法的。再设计状态f[u]为u结点作为孤立点集存在的方案数,f[u]显然是从儿子结点v转移而来,f[u] = ∏ dp[v][0] + dp[v][1] - f[v] 。为什么转移方程要减去f[v]?是因为结点v作为独立点出现时,不能单独存在,所以要令dp[v][1] - f[v]。

    那么新的转移方程就是 :

    dp[u][0] = ∏ dp[v][0] + dp[v][1] + dp[v][0] + dp[v][1] - f[v]  (需要考虑u和v不连边的情况)

    dp[u][1] = ∏ dp[v][0] + dp[v][0] + dp[v][1] - f[v]  (同样需要考虑u和v不连边的情况,此时v可以是独立点)

    f[u] = ∏ dp[v][0] + dp[v][1] - f[v]

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 3e5+5;
     5 const ll mod = 998244353;
     6 vector<int> g[maxn];
     7 ll dp[maxn][3],f[maxn];
     8 void dfs(int cur,int fa){
     9     dp[cur][0] = dp[cur][1] = f[cur] = 1;
    10     for(int i = 0;i<g[cur].size();i++){
    11         int v = g[cur][i];
    12         if(v == fa) continue;
    13         dfs(v,cur);
    14         dp[cur][0] = dp[cur][0] * ((2 * dp[v][0] + 2 * dp[v][1] - f[v])%mod) % mod;
    15         dp[cur][1] = dp[cur][1] * ((2 * dp[v][0] + dp[v][1] - f[v]) % mod) % mod;
    16         f[cur] = f[cur] * ((dp[v][0] + dp[v][1] - f[v]) % mod) % mod;
    17     }
    18 }
    19 int main() {
    20     int n;
    21     scanf("%d",&n);
    22     for(int i = 1;i<n;i++){
    23         int u,v;
    24         scanf("%d%d",&u,&v);
    25         g[u].push_back(v);
    26         g[v].push_back(u);
    27     }
    28     dfs(1,0);
    29     cout<<(dp[1][0]+dp[1][1]-f[1]-1+3*mod)%mod;
    30     return 0;
    31 }
  • 相关阅读:
    SQL Server 创建触发器(trigger)
    jQuery插件-json2.js
    Opengl创建机器人手臂代码示例
    OpenGL超级宝典完整源码(第五版)
    基于Opengl的太阳系动画实现
    Opengl创建几何实体——四棱锥和立方体
    ubuntu16.04安装labelme
    Visual Studio Command Prompt 工具配置方法
    OpenNi安装示例
    Opencv读取图片像素值并保存为txt文件
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12657265.html
Copyright © 2011-2022 走看看