CodeForces 109C 树形DP Lucky Tree

赶脚官方题解写得挺清楚的说,=_=

注意数据范围用long long,否则会溢出。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 using namespace std;
 7 
 8 const int maxn = 100000 + 10;
 9 
10 int n;
11 vector<int> G[maxn], C[maxn];
12 
13 inline int lucky(int x)
14 {
15     while(x)
16     {
17         if(x % 10 != 4 && x % 10 != 7) return 0;
18         x /= 10;
19     }
20     return 1;
21 }
22 
23 long long d[maxn], sz[maxn], f[maxn];
24 
25 void dfs(int u, int fa)
26 {
27     sz[u] = 1;
28     f[u] = 0;
29     for(int i = 0; i < G[u].size(); i++)
30     {
31         int v = G[u][i];
32         if(v == fa) continue;
33         dfs(v, u);
34         sz[u] += sz[v];
35         if(C[u][i]) f[u] += sz[v];
36         else f[u] += f[v];
37     }
38 }
39 
40 void dfs2(int u, int fa)
41 {
42     for(int i = 0; i < G[u].size(); i++)
43     {
44         int v = G[u][i];
45         if(v == fa) continue;
46         if(C[u][i]) d[v] = sz[1] - sz[v];
47         else d[v] = d[u] + f[u] - f[v];
48         dfs2(v, u);
49     }
50 }
51 
52 int main()
53 {
54     //freopen("in.txt", "r", stdin);
55 
56     scanf("%d", &n);
57     for(int i = 1; i < n; i++)
58     {
59         int u, v, d; scanf("%d%d%d", &u, &v, &d);
60         int t = lucky(d);
61         G[u].push_back(v); C[u].push_back(t);
62         G[v].push_back(u); C[v].push_back(t);
63     }
64 
65     dfs(1, 0);
66     dfs2(1, 0);
67 
68     long long ans = 0;
69     for(int i = 1; i <= n; i++) ans += f[i] * (f[i] - 1) + d[i] * (d[i] - 1) + 2 * f[i] * d[i];
70     printf("%I64d\n", ans);
71 
72     return 0;
73 }
代码君

 

posted @ 2015-08-11 09:23  AOQNRMGYXLMV  阅读(290)  评论(0编辑  收藏  举报