空降题目处(外网)
点我点我点我
空降题目处(内网)
点我点我点我
Description
对于一棵树,独立集是指两两互不相邻的节点构成的集合。例如,图1有5个不同的独立集(1个双点集合、3个单点集合、1个空集),图2有14个不同的独立集,图3有5536个不同的独立集。
Input
第一行一个正整数n,表示点的数量。n最大为100000。
接下来n-1行,有两个整数a、b,表示编号为a、b的两个点之间有一条边,其中a、b大于等于1,小于等于n。
Output
输出一行,包含一个整数,表示独立集的数量。由于这个数很大,你只需要输出这个数除以10081的余数。
Solution
设
Soni
为节点
i
的儿子,以
Fi=∏Soni,0j=1Soni,j+∏SonSoni,j,0k=1SonSoni,j,k
普及一下:
∏ni=1ai=a1×a2×⋯×an−1×an
Code
C++
#include<cstdio>
#include<fstream>
#include<cmath>
#include<cstring>
using namespace std;
int ans,n,a[200001],b[200001],s[100001],e[100001],son[100001][300],f[100001];
void sort(int l,int r);
void Dfs(int x,int l);
void Get(int x);
int main()
{
scanf("%d",&n);
for (int i=1;i<=n-1;i++)
{
scanf("%d%d",&a[i*2],&b[i*2]);
a[i*2-1]=b[i*2];
b[i*2-1]=a[i*2];
}
sort(1,2*n-2);
for (int i=0;i<=2*n-2;i++)
if (a[i]!=a[i+1])
{
e[a[i]]=i;
s[a[i+1]]=i+1;
}
Dfs(1,0);
Get(1);
ans=f[1];
printf("%d",ans);
}
void sort(int l,int r)
{
int i=l,j=r,m=a[(l+r)/2];
do
{
while (a[i]<m)
i++;
while (m<a[j])
j--;
if (i<=j)
{
swap(a[i],a[j]);
swap(b[i],b[j]);
i++;
j--;
}
}
while (i<=j);
if (i<r)
sort(i,r);
if (l<j)
sort(l,j);
}
void Dfs(int x,int l)
{
for (int i=s[x];i<=e[x];i++)
if ((b[i]!=l)&&(b[i]!=0))
{
son[x][++son[x][0]]=b[i];
Dfs(b[i],x);
}
}
void Get(int x)
{
int p=1,q=1;
for (int i=1;i<=son[x][0];i++)
{
if (f[son[x][i]]==0)
Get(son[x][i]);
p=(p*f[son[x][i]])%10081;
for (int j=1;j<=son[son[x][i]][0];j++)
q=(q*f[son[son[x][i]][j]])%10081;
}
f[x]=(p+q)%10081;
}
Pascal
var
i,j,k,l,n,m,x,y:longint;
last,next,a:array[0..200001] of longint;
f:array[1..100001,0..1] of longint;
procedure sxdp(x,y:longint);
var
q:longint;
begin
q:=last[y];
f[y,0]:=1;
f[y,1]:=1;
while q<>0 do
begin
if a[q]<>x then
begin
sxdp(y,a[q]);
f[y,0]:=f[a[q],1]*f[y,0] mod 10081;
f[y,1]:=((f[a[q],0]+f[a[q],1])*f[y,1]) mod 10081;
end;
q:=next[q];
end;
end;
begin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
readln(n);
for i:=1 to n-1 do
begin
readln(x,y);
inc(m);
a[m]:=y;
next[m]:=last[x];
last[x]:=m;
inc(m);
a[m]:=x;
next[m]:=last[y];
last[y]:=m;
end;
sxdp(-1,1);
writeln((f[1,0]+f[1,1]) mod 10081);
end.