湖南省队御用绫厨TM_Sharweek
2024-11-20 22:05:34
到底是谁在做这些题的翻译怎么输入输出格式都不给一下。
给出一棵无根树,你可以对一个点选择染或者不染,不能有两个相邻节点都染色。求总的方案数。
先输入一个数
第
输出一行一个整数,表示总方案数对
这种奇奇怪怪数数题大概率是计数 DP 了,所以往树形计数 DP 的方向思考。
我们先构造一个十分无脑的状态:
给出这个状态后,推出转移方程是十分简单的。因为每棵子树都是相对独立的,可以看作是把
以下是我的 C++ 代码
/*********************************************************************
程序名:
版权:
作者:
日期: 2024-11-20 21:43
说明:
*********************************************************************/
#include <bits/stdc++.h>
#define m_p make_pair
#define p_b push_back
#define fst first
#define sec second
#define p_q priority_queue
#define u_map unordered_map
using namespace std;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128;
const int N = 1e5 + 50;
const ll P = 1e9 + 7;
vector<int> g[N];
ll f[N][2];
void dfs(int u, int fa) {
f[u][1] = f[u][0] = 1;
for (int v : g[u]) {
if (v == fa) {
continue;
}
dfs(v, u);
f[u][1] = (f[u][1] * f[v][0]) % P;
f[u][0] = (f[u][0] * (f[v][1] + f[v][0])) % P;
}
}
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
g[u].p_b(v);
g[v].p_b(u);
}
dfs(1, 0);
cout << (f[1][1] + f[1][0]) % P << endl;
return 1007120412;
}