题目大意
对于一棵树,独立集是指两两互不相邻的节点构成的集合。例如,图
1
1
1有
5
5
5个不同的独立集(
1
1
1个双点集合、
3
3
3个单点集合、
1
1
1个空集),图
2
2
2有
14
14
14个不同的独立集,图
3
3
3有
5536
5536
5536个不同的独立集。
题目解析
树形
D
P
DP
DP
设
F
[
i
]
[
1
]
F[i][1]
F[i][1]表示以第
i
i
i个节点为根的子树并且选
i
i
i构成独立集的最多独立集数量。
F
[
i
]
[
2
]
F[i][2]
F[i][2]表示以第
i
i
i个节点为根的子树并且不选
i
i
i构成独立集的最多独立集数量。
对于每一个叶子节点,都将
F
[
]
[
1
]
=
F
[
]
[
2
]
=
1
F[][1]=F[][2]=1
F[][1]=F[][2]=1。
状态转移:
F
[
i
]
[
1
]
=
F
[
i
的
所
有
子
节
点
]
[
2
]
的
乘
积
再
取
m
o
d
F[i][1]=F[i的所有子节点][2]的乘积再取mod
F[i][1]=F[i的所有子节点][2]的乘积再取mod
表示为选择当前节点
i
i
i,因为与子节点相邻,所以
i
i
i的所有子节点都不选。
F
[
i
]
[
2
]
=
(
F
[
i
的
所
有
子
节
点
]
[
1
]
+
F
[
i
的
所
有
子
节
点
]
[
2
]
)
的
乘
积
再
取
m
o
d
F[i][2]=(F[i的所有子节点][1]+F[i的所有子节点][2])的乘积再取mod
F[i][2]=(F[i的所有子节点][1]+F[i的所有子节点][2])的乘积再取mod
表示为不选择当前节点
i
i
i,因为与子节点无关了,所以把所有情况都相乘得出答案
最后 A n s = ( F [ 1 ] [ 1 ] + F [ 1 ] [ 2 ] ) Ans=(F[1][1]+F[1][2]) Ans=(F[1][1]+F[1][2]) m o d mod mod 10081 10081 10081
代码
#include<bits/stdc++.h>
#define N 100005
#define M 10081
using namespace std;
int n,cnt;
int v[N*2],next[N*2],last[N*2];
long long f[N][3];
bool flag[N];
void ins(int x,int y)
{
cnt++;
v[cnt]=y;
next[cnt]=last[x];
last[x]=cnt;
}
void dfs(int x)
{
int f1=1,f2=1,k;
flag[x]=1;
k=last[x];
while(k!=0)
{
if(!flag[v[k]])
{
dfs(v[k]);
f1=(f1*f[v[k]][2])%M;
f2=(f2*(f[v[k]][1]+f[v[k]][2]))%M;
}
k=next[k];
}
f[x][1]=f1;
f[x][2]=f2;
}
int main()
{
cin>>n;
int x,y;
for(int i=1;i<n;i++)
{
cin>>x>>y;
ins(x,y);ins(y,x);
}
dfs(1);
cout<<(f[1][1]+f[1][2])%M;
}