根据树的性质进行两个深度优先搜索就可以了,要注意数据的范围。
代码如下:
#include <iostream> #include <vector> using namespace std; const int MAX_N = 1e6+10; const long long MOD = 1e9+7; int n; vector<int> nd[MAX_N]; // 连接的顶点 long long ans[MAX_N]; inline long long fastpow(long long x, int k) { long long res = 1, t = x; while(k) { if(k & 1) res = res * t % MOD; t = t * t % MOD; k >>= 1; } return res; } inline long long inv(long long x){ return fastpow(x, MOD - 2); } void dfs1(int p, int cur){ int size = nd[cur].size(), son; for(int i = 0; i < size; ++i){ son = nd[cur][i]; if(son == p) continue; dfs1(cur, son); ans[cur] = (ans[cur]*(ans[son]+1)) % MOD; } } void dfs2(int p, int cur){ int size = nd[cur].size(), son; long long tm = 1; for(int i = 0; i < size; ++i){ son = nd[cur][i]; if(son == p) continue; if((ans[son] + 1) % MOD != 0){ tm = tm*(ans[son] + 1) % MOD; ans[son] = ans[son]*((ans[cur]*inv(ans[son] + 1) + 1) % MOD) % MOD; }else{ if(tm != 0){ for(int j = i + 1; j < size; ++j){ if(tm == 0) break; tm = tm*(ans[nd[cur][j]] + 1) % MOD; } ans[son] = ans[son]*(tm + 1) % MOD; tm = 0; } } dfs2(cur, son); } } int main(){ scanf("%lld",&n); int x, y; for(int i = 1; i < n; ++i){ scanf("%d%d",&x, &y); nd[y].push_back(x); nd[x].push_back(y); } for(int i = 1; i <= n; ++i) ans[i] = 1; dfs1(0, 1); dfs2(0, 1); for(int i = 1; i <= n; ++i) printf("%lld\n",ans[i]); }