动态规划
我们看题目后知道这是一棵无根树,要求出有多少子树
我们设$f[u][1]$表示选了当前节点$u$的方案数
相反的$f[u][0]$则为不选中$u$
那么考虑状态转移如下:
f[u][1]=(f[u][1]*(1+f[v][1]))%mod; f[u][0]=(f[u][0]+(f[v][1]+f[v][0]%mod))%mod;
第二个就不解释了,第一个根据加法原则可以知道
代码实现:
#include<iostream> #include<cstdio> #include<algorithm> #define mod 1000000007 #define N 100007 #define int long long using namespace std; struct Edge { int to,nxt; }edge[N<<1]; int head[N],f[N][2]; int n,cnt; void Add(int x,int y) { edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } void Dfs(int u,int fa) { f[u][1]=1; for(int i=head[u];i;i=edge[i].nxt) { int v=edge[i].to; if(v==fa) continue; Dfs(v,u); f[u][1]=(f[u][1]*(1+f[v][1]))%mod; f[u][0]=(f[u][0]+(f[v][1]+f[v][0]%mod))%mod; } } signed main() { scanf("%lld",&n); for(int i=1;i<n;++i) { int x,y; scanf("%lld%lld",&x,&y); Add(x,y); Add(y,x); } Dfs(1,0); printf("%lld",(f[1][0]+f[1][1])%mod); return 0; }