Lucky Tree

题目:http://codeforces.com/problemset/problem/109/C

题意:一棵树n个节点,组成一个图,每条边都有权值,对于i、j、k三个数,计算所有的 i 到 j 和 i 到 k 的路径上有幸运数的三元组个数。

题解:用并查集来做,对于任意节点 i ,找出与 i 连通的且某段路径的权值是幸运数的点的个数num,则总个数即是1~n的num*(num-1).但是因为有些点之间是间接连接的,无法直接判断,所以用并查集来更新,计算出每个点的根节点的num值(额,每个点的num值也无法直接计算,因为有的间接连接的点也符合,但可以通过两点的权值计算点与 i 的不符合的点的个数,用n减去它就是所需的  num)。在后面计算总数时,遍历每个点时用其根节点的num值来计算。

 

这两天整个人敲题都是迷的.........

 1 #include <map>
 2 #include <stack>
 3 #include <queue>
 4 #include <cmath>
 5 #include <string>
 6 #include <limits>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cstdlib>
10 #include <cstring>
11 #include <iostream>
12 #include <algorithm>
13 #define Scc(c) scanf("%c",&c)
14 #define Scs(s) scanf("%s",s)
15 #define Sci(x) scanf("%d",&x)
16 #define Sci2(x, y) scanf("%d%d",&x,&y)
17 #define Sci3(x, y, z) scanf("%d%d%d",&x,&y,&z)
18 #define Scl(x) scanf("%I64d",&x)
19 #define Scl2(x, y) scanf("%I64d%I64d",&x,&y)
20 #define Scl3(x, y, z) scanf("%I64d%I64d%I64d",&x,&y,&z)
21 #define Pri(x) printf("%d\n",x)
22 #define Prl(x) printf("%I64d\n",x)
23 #define Prc(c) printf("%c\n",c)
24 #define Prs(s) printf("%s\n",s)
25 #define For(i,x,y) for(int i=x;i<y;i++)
26 #define For_(i,x,y) for(int i=x;i<=y;i++)
27 #define FFor(i,x,y) for(int i=x;i>y;i--)
28 #define FFor_(i,x,y) for(int i=x;i>=y;i--)
29 #define Mem(f, x) memset(f,x,sizeof(f))
30 #define LL long long
31 #define ULL unsigned long long
32 #define MAXSIZE 100005
33 #define INF 0x3f3f3f3f
34 const int mod=1e9;
35 const double PI = acos(-1.0);
36 
37 using namespace std;
38 
39 int pre[MAXSIZE];
40 int num[MAXSIZE];
41 int find(int x)
42 {
43     if(x!=pre[x])
44         return pre[x]=find(pre[x]);
45     return x;
46 }
47 int check(int n)
48 {
49     while(n)
50     {
51         if(n%10!=4&&n%10!=7)
52             return 0;
53         n/=10;
54     }
55     return 1;
56 }
57 void hhh(int x,int y)
58 {
59     x=find(x);
60     y=find(y);
61     if(x==y)
62         return ;
63     pre[y]=x;
64     num[x]+=num[y];
65 }
66 int main()
67 {
68     int n;
69     Sci(n);
70     For_(i,1,n)
71     {
72         num[i]=1;
73         pre[i]=i;
74     }
75 
76     int a,b,c;
77     For_(i,1,n-1)
78     {
79         Sci3(a,b,c) ;
80         if(!check(c))
81         {
82             hhh(a,b);
83         }
84     }
85     LL sum=0;
86     For_(i,1,n)
87     {
88         int tmp=n-num[ find( i) ];
89         sum+=(LL)(tmp-1)*tmp;//这个地方的(LL)不能省,乘积结果应该是会超出int范围
90     }
91     Prl(sum);
92     return 0;
93 }
View Code

 

posted @ 2019-08-25 22:20  hbhdhd  阅读(332)  评论(0编辑  收藏  举报