zoukankan      html  css  js  c++  java
  • 【USACO 2019 December Silver】Milk Visits题解

    题目描述
    Farmer John 计划建造 N(1≤N≤10^5)个农场,用 N−1 条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。
    Farmer John 的 M 个朋友(1≤M≤10^5)经常前来拜访他。在朋友 i 拜访之时,Farmer John 会与他的朋友沿着从农场 Ai 到农场 Bi 之间的唯一路径行走(可能有 Ai=Bi)。除此之外,他们还可以品尝他们经过的路径上任意一头奶牛的牛奶。由于 Farmer John 的朋友们大多数也是农场主,他们对牛奶有着极强的偏好。他的有些朋友只喝更赛牛的牛奶,其余的只喝荷斯坦牛的牛奶。任何 Farmer John 的朋友只有在他们访问时能喝到他们偏好的牛奶才会高兴。
    请求出每个朋友在拜访过后是否会高兴。

    输入
    输入的第一行包含两个整数 N 和 M。
    第二行包含一个长为 N 的字符串。如果第 i 个农场中的奶牛是更赛牛,则字符串中第 i 个字符为 ‘G’,如果第 i 个农场中的奶牛是荷斯坦牛则为 ‘H’。
    接下来下 N−1 行,每行包含两个不同的整数 X 和 Y(1≤X,Y≤N),表示农场 X 与 Y 之间有一条道路。
    接下来下 M 行,每行包含整数 Ai,Bi,以及一个字符 Ci。Ai 和 Bi 表示朋友 i 拜访时行走的路径的端点,Ci 是 ‘G’ 或 ‘H’ 之一,表示第 i 个朋友喜欢更赛牛的牛奶或是荷斯坦牛的牛奶。

    输出
    输出一个长为 M 的二进制字符串。如果第 i 个朋友会感到高兴,则字符串的第 i 个字符为 ‘1’,否则为 ‘0’。

    样例输入
    5 5
    HHGHG
    1 2
    2 3
    2 4
    1 5
    1 4 H
    1 4 G
    1 3 G
    1 3 H
    5 5 H

    样例输出
    10110

    数据范围限制
    测试点 2-5 满足 N≤10^ 3,M≤2⋅10^3。
    全部测试点满足 N≤10^ 5,M≤10^5。

    提示
    在这里,从农场 1 到农场 4 的路径包括农场 1、2 和 4。所有这些农场里都是荷斯坦牛,所以第一个朋友会感到满意,而第二个朋友不会。
    介绍一种并查集的写法

    思路

    因为题目只有2种颜色,那么我们把同一种颜色连在一起的放在同一个连通块里面,也就是把两个点合并,查询的时候如果两个点没有公共祖先,那么他一定经过了2种颜色,如果是相同的公共祖先,那么我们只要判断它的节点的颜色是不是查询的颜色。

    具体写法看代码(这次我竟然给代码,不可能的 ),如果会并查集的话理解还是比较简单的。

    #include<bits/stdc++.h>   //请勿抄袭
    using namespace std;
    int n,m,b[100005],x,y;
    char c[100005],z;
    int find(int p){
        if(b[p]!=p){
            b[p]=find(b[p]);
        }
        return b[p];
    }
    int main(){
    	freopen("milkvisits.in","r",stdin);
    	freopen("milkvisits.out","w",stdout);
    	scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
        	c[i]=getchar();
        	while(c[i]!='H'&&c[i]!='G') c[i]=getchar();
        	b[i]=i;
    	}
        for(int i=1;i<n;i++){
        	scanf("%d%d",&x,&y);
            if(c[x]==c[y])b[find(x)]=find(y);
        }
        for(int i=1;i<=m;i++){
        	scanf("%d%d",&x,&y);
        	z=getchar();
        	while(z!='H'&&z!='G') z=getchar();
        	if(find(x)!=find(y)||c[x]==z)
            	printf("1");
            else printf("0");
        }
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    C#实现-浏览器UA解析获得手机、系统、浏览器等信息
    C#代码实现-冒泡排序
    C# DateTime 工具类
    net core 3.1 跨域 Cors 找不到 “Access-Control-Allow-Origin”
    C#/.Net开发入门篇(3)——console类的输入输出
    C#/.Net开发入门篇(2)——第一个控制台应用程序
    C#/.Net开发入门篇(1)——开发工具安装
    docker 学习笔记(2)--docker file命令
    docker 学习笔记(1)--常用命令
    导出大数据方法。批量导BOM
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13159890.html
Copyright © 2011-2022 走看看