P5836 [USACO19DEC]Milk Visits S

题目描述

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;
}
发布了124 篇原创文章 · 获赞 47 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/ludan_xia/article/details/105061904