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 ightarrow y) 这条边的状态。
-
该边在subgraph 中,则 x 的状态与 y 的状态有关联
-
该边不在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 ightarrow y) 这条边不被选中,则 y 被选中的状态 (d[y][1]) 应该减去 (f[y]), 这代表着 y 不能作为单点被选中,所以有如下转移:
最终答案应该是 (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 << "