您的位置:首页 > 其它

HDU5647 Tree DP

2016-03-21 16:33 357 查看
  这个题的意思是树的所有连通量的个数之和, 我们定义g[i]为以i为根的子数的个数, f[i]为以i为根的所有连通分量元素个数之和, 那么f[u] = f[u]*(g[v]+1) + f[v]*g[u]; g[u] = g[u]*(g[v]+1); 然后在回溯的时候计算一下即可, 代码如下:

#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;
typedef long long LL;
const LL m = 1e9+7;
vector<int> G[200000 + 100];
int n;
LL g[200000+100];
LL f[200000+100];

LL ans;
void dfs(int u, int pre){
g[u]=1; f[u]=1;
for(int i=0; i<G[u].size(); i++) {
int v = G[u][i];
if(v != pre) {
dfs(v, u);
f[u] = (f[u]*(g[v]+1) + f[v]*g[u])%m;
g[u] = g[u]*(g[v]+1)%m;
}
}
ans = (ans + f[u])%m;
}

int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i=1; i<=200000; i++) G[i].clear();
int pi;
for(int i=2; i<=n; i++) {
scanf("%d", &pi);
G[i].push_back(pi);
G[pi].push_back(i);
}
ans = 0;
memset(f, 0, sizeof(f));
dfs(1, -1);
//        LL res = 0;
// for(int i=1; i<=200000; i++) res = (res + f[i])%m;

printf("%lld\n", ans);
//        printf("%lld\n", res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: