F. Independent Set

题意

一颗 n 个节点的树,求出每个\(edge-induced~subgraph\)的独立集个数之和。

\(edge-induced~subgraph\)含义是对于边集\(E,(E'\subset E)\),\(E\) 中的所有点都在该子图中。

注意到题目要求的结果中,E' 不能为空

分析

首先选出子图,问题转换成在森林中选出一些点,他们互相没有边,求这样的点集的个数。对于一棵树上的问题,可以用树形DP求出

设 \(d[x][0]\) 表示不选 x 的方案数,\(d[x][1]\) 表示选 x 的方案数

\(d[x][0] = \prod (d[y][1] + d[y][0])\\d[x][1] = \prod d[y][0]\)

但是此题中 x 和 y 不一定在一棵树中,所以还要考虑 \(x\rightarrow y\) 这条边的状态。

  1. 该边在subgraph 中,则 x 的状态与 y 的状态有关联

  2. 该边不在subgraph中,则 x 的状态与 y 的状态没有关联

考虑这两种状态,有转移方程:

\(d[x][0] = \prod 2 * (d[y][1] + d[y][0])\)

\(d[x][1] = \prod (d[y][0] + d[y][1] + d[y][0])\)

到这里似乎问题已经得到解决,但是要注意到,“单点” 这种情况是不允许出现的,因为题目中的子图是由边集构造的,所以要考虑去除掉这种情况。

设 \(f[x]\) 表示 x 与所有的子节点 y 所连的边都不在子图中的方案数

在用 \(f[y]\) 去更新 x 时,如果 \(x\rightarrow y\) 这条边不被选中,则 y 被选中的状态 \(d[y][1]\) 应该减去 \(f[y]\), 这代表着 y 不能作为单点被选中,所以有如下转移:

\[\begin{cases}
d[x][0]= \prod (d[y][1]+d[y][0]) + (d[y][1]-f[y]+d[y][0]) \\
d[x][1] = \prod (d[y][0]) + (d[y][1] - f[y] + d[y][0])\\
f[x] = \prod (d[y][1]-f[y]+d[y][0])
\end{cases}
\]

最终答案应该是 \(d[1][0]+d[1][1]-f[1]-1\), 最后减去 1 是减去了空子图的情况

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 300000 + 5;
const int mod = 998244353;
int head[N], ver[N<<1], nxt[N<<1], tot;
int n;
ll d[N][2], f[N];
void add(int x, int y){
ver[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}
void dfs(int x, int fa){
d[x][0] = d[x][1] = f[x] = 1;
for(int i=head[x];i;i=nxt[i]){
int y = ver[i];
if(y == fa) continue;
dfs(y, x);
d[x][0] = d[x][0] * ((2 * d[y][0] + 2 * d[y][1] - f[y])%mod) % mod;
d[x][1] = d[x][1] * ((2 * d[y][0] + d[y][1] - f[y]) % mod) % mod;
f[x] = f[x] * ((d[y][0] + d[y][1] - f[y]) % mod) % mod;
}
dbg(x, d[x][0], d[x][1], f[x]);
}
int main(){
scanf("%d", &n);
for(int i=2;i<=n;i++){
int x, y;
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
dfs(1, 0);
cout << (d[1][0] + d[1][1] - f[1] - 1 + 2 * mod) % mod;
return 0;
}

这题代码很容易写,关键是要把DP转移搞清楚,CF的题目解释很清晰,而且样例还给解释,要是放在比赛上能遇到这样的Hint就谢天谢地了

CF-1332 F. Independent Set的更多相关文章

  1. CF R 630 div2 1332 F Independent Set

    LINK:Independent Set 题目定义了 独立集和边诱导子图.然而和题目没有多少关系. 给出一棵树 求\(\sum_{E'\neq \varnothing,E'\subset E}w(G( ...

  2. CF 633 F. The Chocolate Spree 树形dp

    题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...

  3. CF #271 F Ant colony 树

    题目链接:http://codeforces.com/contest/474/problem/F 一个数组,每一次询问一个区间中有多少个数字可以整除其他所有区间内的数字. 能够整除其他所有数字的数一定 ...

  4. CF 494 F. Abbreviation(动态规划)

    题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...

  5. CF 1138 F. Cooperative Game

    F. Cooperative Game 链接 题意: 有10个玩家,开始所有玩家在home处,每次可以让一些玩家沿着边前进一步,要求在3(t+c)步以内,到达终点. 分析: 很有意思的一道题.我们构造 ...

  6. CF 1041 F. Ray in the tube

    F. Ray in the tube 链接 题意: 有两条平行于x轴的直线A,B,每条直线上的某些位置有传感器.你需要确定A,B轴上任意两个整点位置$x_a$,$x_b$,使得一条光线沿$x_a→x_ ...

  7. 【Cf #502 F】The Neutral Zone

    本题把$log$化简之后求得就是每个质数$f$前的系数,求系数并不难,难点在于求出所有的质数. 由于空间限制相当苛刻,$3e8$的$bitset$的内存超限,我们考虑所有的除了$2$和$3$以外的质数 ...

  8. CF 868 F. Yet Another Minimization Problem

    F. Yet Another Minimization Problem http://codeforces.com/contest/868/problem/F 题意: 给定一个长度为n的序列.你需要将 ...

  9. CF 1051 F. The Shortest Statement

    F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...

随机推荐

  1. Lagom 官方文档之随手记

    引言 Lagom是出品Akka的Lightbend公司推出的一个微服务框架,目前最新版本为1.6.2.Lagom一词出自瑞典语,意为"适量". https://www.lagomf ...

  2. 数仓建设中最常用模型--Kimball维度建模详解

    数仓建模首推书籍<数据仓库工具箱:维度建模权威指南>,本篇文章参考此书而作.文章首发公众号:五分钟学大数据,公众号中发送"维度建模"即可获取此书籍第三版电子书 先来介绍 ...

  3. 深入了解MySQL主从复制的原理

    欢迎微信关注「SH的全栈笔记」 0. 主从复制 首先主从复制是什么?简单来说是让一台MySQL服务器去复制另一台MySQL的数据,使两个服务器的数据保持一致. 这种方式与Redis的主从复制的思路没有 ...

  4. oracle坚决不挂01(表,索引,视图的创建,修改,删除,查询)

    考试快来了,来篇oracle干货,复习一下(挣扎一下) 废话不多说,开始写! 这篇是数据库对象的有关操作的总结! 数据库对象有熟悉的表,视图,索引,序列,同义词等(这个oracle东西真不少,小声bb ...

  5. Docker Harbor 高可用 1.7.5版本(七)

    环境说明: node1 10.10.5.135 仓库 1 node2 10.10.5.136 仓库 2 node3 10.10.5.137 客户端 实验内容: Harbor 可以在两台主机之间相互同步 ...

  6. java创建线程安全的类

    如果一个对象想要被多个线程安全的并发访问,那么这个对象必须是或线程安全的或事实不可变的或由锁来保护的. 1.java监视器模式 大多数对象都是组合对象.当从头开始构建一个类,或者将多个非线程安全的类组 ...

  7. pandas DataFrame的新增行列,修改、删除、筛选、判断元素以及转置操作

    1)指定行索引和列索引标签 index 属性可以指定 DataFrame 结构中的索引数组,  columns 属性可以指定包含列名称的行, 而使用 name 属性,通过对一个 DataFrame 实 ...

  8. Java-Servlet知识总结

    目录 Servlet概述 为什么要学习Servlet 什么是 Servlet 工作流程 生命周期 处理请求的方法 HttpServletRequest 和 HttpServletResponse Ht ...

  9. HTML基础复习2

    6.表格 6.1建立表格: 表格由<table></table>标签来定义 每行由<tr></tr>来定义,每行被分割为若干单元格,由<td> ...

  10. Socket.IO基础教程

    什么是Socket.IO Socket.IO是一个库,可用于在浏览器和服务器之间进行实时,双向和基于事件的通信.它包括: 使Node.js服务器:来源 | API 为浏览器(可从Node.js的也运行 ...