题目描述
Farmer John 计划建造 NN 个农场,用 N-1N−1 条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。
Farmer John 的 MM 个朋友经常前来拜访他。在朋友 ii 拜访之时,Farmer John 会与他的朋友沿着从农场 A_iAi 到农场 B_iBi 之间的唯一路径行走(可能有 A_i = B_iAi=Bi)。除此之外,他们还可以品尝他们经过的路径上任意一头奶牛的牛奶。由于 Farmer John 的朋友们大多数也是农场主,他们对牛奶有着极强的偏好。他的有些朋友只喝更赛牛的牛奶,其余的只喝荷斯坦牛的牛奶。任何 Farmer John 的朋友只有在他们访问时能喝到他们偏好的牛奶才会高兴。
请求出每个朋友在拜访过后是否会高兴。
输入格式
输入的第一行包含两个整数 NN 和 MM。
第二行包含一个长为 NN 的字符串。如果第 ii 个农场中的奶牛是更赛牛,则字符串中第 ii 个字符为 G
,如果第 ii 个农场中的奶牛是荷斯坦牛则为 H
。
以下 N-1N−1 行,每行包含两个不同的整数 XX 和 YY(1 \leq X, Y \leq N1≤X,Y≤N),表示农场 XX 与 YY 之间有一条道路。
以下 MM 行,每行包含整数 A_iAi,B_iBi,以及一个字符 C_iCi。A_iAi 和 B_iBi 表示朋友 ii 拜访时行走的路径的端点,C_iCi 是 G
或 H
之一,表示第 ii 个朋友喜欢更赛牛的牛奶或是荷斯坦牛的牛奶。
输出格式
输出一个长为 MM 的二进制字符串。如果第 ii 个朋友会感到高兴,则字符串的第 ii 个字符为 1
,否则为 0
。
输入输出样例
输入 #1复制
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
输出 #1复制
10110
说明/提示
在这里,从农场 1 到农场 4 的路径包括农场 1、2 和 4。所有这些农场里都是荷斯坦牛,所以第一个朋友会感到满意,而第二个朋友不会。
关于部分分:
测试点 11 样例。
测试点 2\sim 52∼5 满足 N\le 10^3N≤103,M\le 2\cdot 10^3M≤2⋅103。
对于 100\%100% 的数据,1 \leq N \leq 10^51≤N≤105,1 \leq M \leq 10^51≤M≤105。
供题:Spencer Compton
解题思路: 对于每一个 朋友出发过程 ,我通过遍历树,建立 相应的路径,然后再 判断 路径 是否满足条件
但是 这样肯定 会TLE 待修改!
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#define maxn 100005
using namespace std;
int n,m;
string path;
vector<int> v[maxn];
bool flag[maxn];
vector<int>P;
bool DFS(int begin,int end,char ch){
/*if(path[begin-1]==ch)
return true;*/
// cout<<"begin "<<begin<<" end "<<end<<endl;
if(begin==end){
int b = false;
for(int i=0;i<P.size();i++){
if(path[P[i]-1]==ch){
b = true;
break;
}
}
return b;
}
for(int i=0;i<v[begin].size();i++){
if(flag[v[begin][i]]==1) continue; //该点访问过了
flag[v[begin][i]] = 1;
// cout<<"v[begin][i]"<<v[begin][i]<<endl;
P.push_back(v[begin][i]);
if(DFS(v[begin][i],end,ch)){
return true;
}
P.pop_back();
flag[v[begin][i]] = 0;
}
return false;
}
int main(){
cin>>n>>m;
cin>>path;
for(int i=1;i<=n-1;i++){
int begin,end;
scanf("%d %d",&begin,&end);
// cin>>begin>>end;
v[begin].push_back(end);
v[end].push_back(begin);
}
/* for(int i=1;i<=n;i++){
for(int j=0;j<v[i].size();j++)
cout<<v[i][j]<<" ";
cout<<endl;
} */
for(int i=1;i<=m;i++){
P.clear();
memset(flag,0,sizeof(flag));
int begin,end;
char ch;
scanf("%d %d %c",&begin,&end,&ch);
// cin>>begin>>end>>ch;
P.push_back(begin);
flag[begin] = 1;
if(DFS(begin,end,ch))
cout<<"1";
else
cout<<"0";
}
return 0;
}