1 题目描述
2 有机合成是指从较简单的化合物或单质经化学反应合成有机物的过程。
3 有时也包括从复杂原料降解为较简单化合物的过程。
4 由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常要用加热、光照、加催化剂、加有机溶剂甚至加压等反应条件。
5 但是前人为有机合成提供了许多宝贵的经验。
6 现在已知有K总物质和N个前人已经总结出的合成反应方程式
7 小星想知道在现有M种物质的情况下 能否合成某些物质。
8 输入描述:
9 第一行输入四个整数 K,N,M,Q(K,N,M,Q<=1e5)
10 K表示一共K总物质
11 接下来N行 每行三个数字a b c(任意两个数可能相等)
12 表示a和b反应可以生成c 反应是可逆的
13 即可以通过c可以分解出a和b
14 接下来一行行然后输入m个数,表示m种原料(每一种原料都可以认为有无限多)
15 接下来Q个行Q个询问
16 对于每个询问
17 输出一个数字 x 判断是否可以通过一些反应得到第 x
18 输出描述:
19 可以得到Yes否则No
20 示例1
21 输入
22 复制
23 10 3 4 10
24 1 2 3
25 4 5 6
26 2 5 7
27 3 4 5 8
28 1
29 2
30 3
31 4
32 5
33 6
34 7
35 8
36 9
37 10
38 输出
39 复制
40 Yes
41 Yes
42 Yes
43 Yes
44 Yes
45 Yes
46 Yes
47 Yes
48 No
49 No
50 说明
51 一共10总物质有第3,4,5,8 四种原料
52 查询每一种是否可以通过反应得到
53 首先通过3可以分解得到1 2
54 然后4 5合成6
55 2 5合成7
56 于是除了9 10都可以得到
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N =1e5+10;
int head[N];
bool vis[N];
int n,m,k,q;
int a,b,c,x,cnt;
struct Edge{
int fr,to,val,nex;
}e[N*4];//add了4次
void add(int a,int b,int c){
e[cnt].fr=a;
e[cnt].val=b;
e[cnt].to=c;
e[cnt].nex=head[a];
head[a]=cnt++;
}
queue<int>Q;
void bfs(){
while(!Q.empty()){
int u= Q.front();
Q.pop();
for(int i=head[u];i!=-1;i=e[i].nex){
Edge ee =e[i];
if(vis[e[i].to]) continue;
if(e[i].val==-1||vis[e[i].val]){
vis[e[i].to]=1;
Q.push(e[i].to);
}
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&k,&q)){
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
cnt=0;
for(int i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c) ;
add(a,b,c);
add(b,a,c);
add(c,-1,a);
add(c,-1,b);
}
for(int i=0;i<k;i++){
scanf("%d",&x);
vis[x]=1;
Q.push(x);
}
bfs();
while(q--){
scanf("%d",&x);
if(vis[x]){
printf("Yes\n");
}
else
printf("No\n");
}
}
return 0;
}