(File IO): input:milkvisits.in output:milkvisits.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
F
a
r
m
e
r
J
o
h
n
Farmer John
FarmerJohn 计划建造
N
(
1
≤
N
≤
1
0
5
)
N(1≤N≤10^5)
N(1≤N≤105)个农场,用
N
−
1
N−1
N−1 条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。
F
a
r
m
e
r
J
o
h
n
Farmer John
FarmerJohn 的
M
M
M 个朋友
(
1
≤
M
≤
1
0
5
)
(1≤M≤10^5)
(1≤M≤105)经常前来拜访他。在朋友
i
i
i 拜访之时,
F
a
r
m
e
r
J
o
h
n
Farmer John
FarmerJohn 会与他的朋友沿着从农场
A
i
Ai
Ai 到农场
B
i
Bi
Bi 之间的唯一路径行走(可能有
A
i
=
B
i
Ai=Bi
Ai=Bi)。除此之外,他们还可以品尝他们经过的路径上任意一头奶牛的牛奶。由于
F
a
r
m
e
r
J
o
h
n
Farmer John
FarmerJohn 的朋友们大多数也是农场主,他们对牛奶有着极强的偏好。他的有些朋友只喝更赛牛的牛奶,其余的只喝荷斯坦牛的牛奶。任何
F
a
r
m
e
r
J
o
h
n
Farmer John
FarmerJohn 的朋友只有在他们访问时能喝到他们偏好的牛奶才会高兴。
请求出每个朋友在拜访过后是否会高兴。
输入
输入的第一行包含两个整数
N
N
N 和
M
M
M。
第二行包含一个长为
N
N
N 的字符串。如果第
i
i
i 个农场中的奶牛是更赛牛,则字符串中第
i
i
i个字符为
′
G
′
'G'
′G′,如果第
i
i
i个农场中的奶牛是荷斯坦牛则为
′
H
′
'H'
′H′。
接下来下
N
−
1
N−1
N−1 行,每行包含两个不同的整数
X
X
X 和
Y
(
1
≤
X
,
Y
≤
N
)
Y(1≤X,Y≤N)
Y(1≤X,Y≤N),表示农场
X
X
X 与
Y
Y
Y 之间有一条道路。
接下来下
M
M
M 行,每行包含整数
A
i
Ai
Ai,
B
i
Bi
Bi,以及一个字符
C
i
Ci
Ci。
A
i
Ai
Ai 和
B
i
Bi
Bi 表示朋友
i
i
i拜访时行走的路径的端点,
C
i
Ci
Ci 是
′
G
′
'G'
′G′ 或
′
H
′
'H'
′H′ 之一,表示第
i
i
i 个朋友喜欢更赛牛的牛奶或是荷斯坦牛的牛奶。
输出
输出一个长为
M
M
M 的二进制字符串。如果第
i
i
i 个朋友会感到高兴,则字符串的第
i
i
i个字符为
′
1
′
'1'
′1′,否则为
′
0
′
'0'
′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
2-5
2−5 满足
N
≤
1
0
3
,
M
≤
2
⋅
1
0
3
N≤10^3,M≤2⋅10^3
N≤103,M≤2⋅103。
全部测试点满足
N
≤
1
0
5
,
M
≤
1
0
5
N≤10^5,M≤10^5
N≤105,M≤105。
提示
在这里,从农场
1
1
1 到农场
4
4
4的路径包括农场
1
、
2
1、2
1、2 和
4
4
4。所有这些农场里都是荷斯坦牛,所以第一个朋友会感到满意,而第二个朋友不会。
解题思路
这道题可以用并查集,把两种牛奶看成两种颜色。
我们可以把同一种颜色合并,然后询问是判断一下一条路的情况就行了:
1.
1.
1. 路上只有一种,那就看看它的颜色与目标一致;
2.
2.
2. 如果路上有两种,就直接1了。
代码
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
string s;
char z;
int n,m,x,y,a[100010],ans[100010];
int find(int x)
{
if(x==a[x])
return x;
else
return a[x]=find(a[x]);
}
int main(){
freopen("milkvisits.in","r",stdin);
freopen("milkvisits.out","w",stdout);
scanf("%d%d",&n,&m);
cin>>s;
for(int i=1;i<=n;i++) a[i]=i;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
if(s[x-1]==s[y-1])
a[find(x)]=find(y);
}
for(int i=1;i<=m;i++)
{
cin>>x>>y>>z;
if(find(x)==find(y)&&s[find(x)-1]==z)
ans[i]=1;
if(find(x)==find(y)&&s[find(x)-1]!=z)
ans[i]=0;
if(find(x)!=find(y))
ans[i]=1;
}
for(int i=1;i<=m;i++)
printf("%d",ans[i]);
}