"Today's Toutiao Cup" The First Hubei University Programming Contest - D. Who killed Cock Robin (tree-shaped DP/multiplication principle)
Topic link: D. Who killed Cock Robin
meaning of the title
Give you a tree (n points, n-1 edges) and let you find the number of connected graph combinations in it, for example, there is a degenerate tree 1->2->3->4, now the connected graph combination here The numbers are (1),(2),(3),(4),(1-2),(2-3),(3-4),(1-2-3),(2-3-4 ), (1-2-3-4) , 10.
ideas
这里先定义每个节点的权值为以该节点为根的子图的种类的数目。那么对于所有叶子节点权值都为1,而对于节点1,需要遍历他的每一个子树,并且子树间的权值需要相乘才得到节点1的权值。请看下图就可以发现它们之间的联系了。每一个now[i]存的都是包括i点在内,不包括父节点,最大数量的连通图。这里的DP其实也用到了乘法原理。
code
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = (int)(j);i <= (int)(k);i ++)
#define per(i,j,k) for(int i = (int)(j);i >= (int)(k);i --)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
typedef long long ll;
const int INF = (int)0x3f3f3f3f;
const int MAXN = (int)2e5+7;
const ll MOD = (ll)1e7+7;
ll now[MAXN];
ll ans;
vector<int> vp[MAXN];
ll dfs(int x){
now[x] = 1;
ll res = 1;
rep(i,0,vp[x].size()-1){
int t = vp[x][i];
if (now[t]) continue;
res = (res*(dfs(t)+1))%MOD;
}
now[x] = res;
return res;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int N;
cin >> N;
rep(i,1,N-1){
int x,y;
cin >> x >> y;
vp[x].pb(y);
vp[y].pb(x);
}
dfs(1);
rep(i,1,N){
ans = (ans+now[i])%MOD;
}
cout << ans << endl;
}