• 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
    ",x)
    22 #define Prl(x) printf("%I64d
    ",x)
    23 #define Prc(c) printf("%c
    ",c)
    24 #define Prs(s) printf("%s
    ",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
  • 相关阅读:
    ASCII码表
    arm linux 下移植busybox 的tftp
    Makefile中的路径
    Wireshark图解教程(简介、抓包、过滤器)【转载】
    在装有windows跟ubuntu的机器上重新安装windows后修复ubuntu的grub
    在linux里建立一个快捷方式,连接到另一个目录
    ubuntu 迁移部分 / 目录下的存储空间到 /home目录
    /etc/ntp.conf
    ntp 配置 autokey 功能【摘录】
    mips-openwrt-linux-gcc test_usbsw.c -o usbsw 编译问题
  • 原文地址:https://www.cnblogs.com/hbhdhd/p/11409678.html
Copyright © 2020-2023  润新知