AT_dp_p Independent Set题解

题目描述

有一棵包含 N 个顶点的树。顶点编号为 1,2,…,N。对于每个 i(1≤i≤N−1),第 i 条边连接顶点 xi​ 和 yi​。

太郎君打算将每个顶点涂成白色或黑色。但要求相邻的两个顶点不能同时被涂成黑色。

请问有多少种顶点着色的方案?请输出方案数对 109+7 取模的结果。

输入格式

输入以如下格式从标准输入读入。

N
x1​ y1​
x2​ y2​

xN−1​ yN−1​

输出格式

输出顶点着色方案数对 109+7 取模的结果。

显示翻译

题意翻译

输入输出样例

输入 #1复制

3
1 2
2 3

输出 #1复制

5

输入 #2复制

4
1 2
1 3
1 4

输出 #2复制

9

输入 #3复制

1

输出 #3复制

2

输入 #4复制

10
8 5
10 8
6 5
1 5
4 8
2 10
3 6
9 2
1 7

输出 #4复制

157

说明/提示

限制条件

  • 所有输入均为整数。
  • 1≤N≤105
  • 1≤xi​,yi​≤N
  • 给定的图是一棵树。

样例解释 1

顶点的着色方案如图,共有 5 种。

样例解释 2

顶点的着色方案如图,共有 9 种。

由 ChatGPT 4.1 翻译

思路

树形DP。

代码见下

#include<bits/stdc++.h> 
using namespace std;
long long n,k,u,vv,f[100005][2],mod=1e9+7;
vector<long long> v[100005];
void abc(long long a1,long long b1){
    f[a1][0]=1;
    f[a1][1]=1;
    for(int i=0;i<v[a1].size();i++){
        long long tt=v[a1][i];
        if(tt!=b1){
            abc(tt,a1);
            f[a1][0]=(f[a1][0]*(f[tt][0]+f[tt][1]))%mod;
            f[a1][1]=(f[a1][1]*f[tt][0])%mod;
        }
    }
    //cout<<a1<<" "<<f[a1][0]<<" "<<f[a1][1]<<endl;
    return ;
}
int main(){
	cin>>n;
    for(int i=1;i<=n-1;i++){
        cin>>u>>vv;
        v[u].push_back(vv);
        v[vv].push_back(u);
    }
    abc(1,0);
    cout<<(f[1][0]+f[1][1])%mod<<endl;
	return 0;
}

posted @ 2025-10-23 10:22  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源