• F1. 生活在树上(easy version)树,dfs


    题目链接

    F1. 生活在树上(easy version)

    题目背景

    本题是 B 组的最后一题,是 F2 题的简单版本,两道题目的解法略有不同。本题和 F2 题在题意上的区别在于本题给定树上的边权,而不是点权。

    小智生活在「传智国」,这是一个有 n n n 个城市的国家,各个城市由 n − 1 n-1 n1 条道路相连。

    每个道路都有长度 w i w_i wi ,我们定义,小智从城市 a a a 走到城市 b b b 的代价是 d i s a , b = ⨁ e ∈ p a t h ( a , b ) w e \mathrm{dis}_{a, b} = \bigoplus \limits_{e \in \mathrm{path}\left(a, b\right)} w_e disa,b=epath(a,b)we,其中 ⨁ \bigoplus 表示按位异或(如果你不知道什么是按位异或,请参见题目下方的提示/说明), p a t h ( a , b ) \mathrm{path}\left(a,b\right) path(a,b) 表示 a a a b b b 的简单路径上的边集。也即 d i s a , b \mathrm{dis}_{a, b} disa,b 表示将 a a a b b b 的简单路径上所有边写作 e 1 , e 2 , e 3 , … e_1, e_2, e_3, \dots e1,e2,e3, 后,求 w e 1 ⨁ w e 2 ⨁ w e 3 … w_{e_1} \bigoplus w_{e_2}\bigoplus w_{e_3} \dots we1we2we3 的结果。

    有一天,小智获得了去参加传智杯的机会,他在前往比赛地的路上想到了一个问题,但他好像不会做,于是他把这个题告诉了你。聪明的同学,你可以帮帮他吗?

    题目描述

    小智说:「由于我们的国家只有 n n n 个城市和 n − 1 n-1 n1 条道路,那么我们的国家就相当于是一棵树。我在想,在我们的国家中,是否有城市满足『到城市 a a a 的代价和到城市 b b b 的代价的异或等于 k k k』。好难哦,我想不出来,你能帮帮我吗?」

    形式化的,给定城市 a , b a, b a,b 和整数 k k k,请你计算有哪几个城市 t t t 满足 d i s t , a ⨁ d i s t , b = k \mathrm{dis}_{t, a} \bigoplus \mathrm{dis}_{t, b} = k dist,adist,b=k

    输入格式

    第一行有两个整数 n n n m m m,表示国家的城市数和询问的个数。

    接下来 n − 1 n-1 n1 行,每行有两个整数 x , y , l x, y, l x,y,l,表示城市 x x x 与城市 y y y 有一条长度为 l l l 的边。

    接下来 m m m 行,每行有三个整数 a , b , k a, b, k a,b,k,表示小智从城市 a a a 走到城市 b b b k k k 的含义与题目描述一致。

    输出格式

    m m m 行,每行一个整数。

    对于第 i i i 个询问,如果存在至少一个城市 t t t 满足要求,则输出 Yes

    如果不存在任何一个城市满足条件,则输出 No

    输出字符串大小写不敏感,例如,YesyESYESyes 等都算作 Yes

    样例 #1

    样例输入 #1

    5 3
    1 2 2
    1 3 6 
    2 4 8
    2 5 1
    1 2 4
    2 3 12
    1 4 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    样例输出 #1

    nO
    No
    YeS
    
    • 1
    • 2
    • 3

    样例 #2

    样例输入 #2

    5 10
    2 1 63
    3 1 57
    4 2 2
    5 2 84
    5 2 84
    4 1 9977404983223574764
    2 5 84
    2 1 15996060349666123522
    5 4 86
    3 1 8428615422876116375
    5 1 107
    2 3 6
    2 3 6
    4 2 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    样例输出 #2

    yeS
    nO
    YEs
    No
    YEs
    nO
    YEs
    yeS
    yeS
    YEs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    提示

    相关概念解释

    「树」:树是一个有 n n n 个结点和 n − 1 n-1 n1 条边的无向简单连通图。

    按位异或」:按位异或即 C++、python、java 语言中的 「^」 运算。它是一个二元运算,步骤是将两个数的二进制位按位比较,相同为 0 0 0,不同为 1 1 1。例如: 3 ⨁ 5 = ( 011 ) 2 ⨁ ( 101 ) 2 = ( 110 ) 2 = 6 3 \bigoplus 5 = (011)_2 \bigoplus (101)_2 = (110)_2 = 6 35=(011)2(101)2=(110)2=6请注意,这是一个按位运算,不是一个逻辑运算

    样例 1 解释

    下图为传智国的地图。

    ∀ t ∈ { 1 , 2 , 3 , 4 , 5 } \forall t \in \{1, 2, 3, 4, 5\} t{1,2,3,4,5},都不可能有 d i s t , 1 ⨁ d i s t , 2 = 4 \mathrm{dis} _{t,1} \bigoplus \mathrm{dis}_{t, 2} = 4 dist,1dist,2=4 d i s t , 2 ⨁ d i s t , 3 = 12 \mathrm{dis}_{t, 2} \bigoplus \mathrm{dis}_{t, 3} = 12 dist,2dist,3=12,于是输出 No

    而取 t = 5 t = 5 t=5,有 d i s t , 1 ⨁ d i s t , 4 = 10 \mathrm{dis}_{t, 1} \bigoplus \mathrm{dis}_{t, 4} = 10 dist,1dist,4=10,于是输出 Yes

    数据规模与约定

    对于所有测试点,保证 1 < n ≤ 5 × 1 0 5 1 < n \leq 5 \times 10^5 1<n5×105 1 ≤ m ≤ 5 × 1 0 5 1 \leq m \leq 5 \times 10^5 1m5×105 0 ≤ w i < 2 64 0 \leq w_i < 2^{64} 0wi<264

    对于每次询问,保证 1 ≤ a , b ≤ n 1 \leq a,b \leq n 1a,bn a ≠ b a \neq b a=b 0 ≤ k < 2 64 0 \leq k < 2^{64} 0k<264
    思路:
    首先需要明确的是和异或的特点,两个相同的数异或的结果为0,任何数异或0之后的仍旧是它本身。所以这道题目,需要注意的就是树的存储方式。只要能选中任何一个点作为起点,计算完到其他n-1个点的异或的结果,就能知道是否满足给定的条件。
    代码:

    #include 
    using namespace std;
    const int maxn=5e5+11;
    #define ll unsigned long long 
    int n,m;
    ll dis[maxn];
    bool flag[maxn];
    struct edge
    {
    	int to;
    	ll v;
    };
    vector<edge> e[maxn];
    void dfs(int x)
    {
    	
    	for(int i=0;i<e[x].size();i++)
    	{
    		ll y=e[x][i].to,z=e[x][i].v;
    		if(flag[y]) continue;
    		dis[y]=dis[x]^z;
    		flag[y]=1;
    		dfs(y);
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<n;i++)
    	{
    		int x,y;
    		ll z;
    		scanf("%d%d%llu",&x,&y,&z);
    		e[x].push_back({y,z});
    		e[y].push_back({x,z});
    	}
    	flag[1]=1;
    	dfs(1);
    	//for(int i=1;i<=n;i++) cout<<"i="<for(int i=1;i<=m;i++)
    	{
    		int a,b;
    		ll k;
    		scanf("%d%d%llu",&a,&b,&k);
    		//cout<<"dis[a]^dis[b="<<(dis[a]^dis[b])<
    		if((dis[a]^dis[b])==k) printf("Yes\n");
    		else printf("No\n");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    《网络协议》04. 应用层(DNS & DHCP & HTTP)
    Java Double compareTo()方法具有什么功能呢?
    【React】React全家桶(五)React Hooks
    COSCon'23 开源市集:共赴一场草坪上的开源派对
    BatchNormalization:解决神经网络中的内部协变量偏移问题
    我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)
    MySQL高阶语句(三)
    Docker Volume(存储卷)
    “漫丝路”主题餐饮空间设计
    云服务器ubuntu20.04安装dotnet6环境
  • 原文地址:https://blog.csdn.net/Rachelhello123/article/details/128068137