链接:https://www.nowcoder.net/acm/contest/78/I
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
有时也包括从复杂原料降解为较简单化合物的过程。
但是前人为有机合成提供了许多宝贵的经验。
现在已知有K总物质和N个前人已经总结出的合成反应方程式
小星想知道在现有M种物质的情况下 能否合成某些物质。
输入描述:
第一行输入四个整数 K,N,M,Q(K,N,M,Q<=1e5)
K表示一共K总物质
接下来N行 每行三个数字a b c(任意两个数可能相等)
表示a和b反应可以生成c 反应是可逆的
即可以通过c可以分解出a和b
接下来一行行然后输入m个数,表示m种原料(每一种原料都可以认为有无限多)
接下来Q个行Q个询问
对于每个询问
输出一个数字 x 判断是否可以通过一些反应得到第 x
输出描述:
可以得到Yes否则No
示例1
输入
10 3 4 10 1 2 3 4 5 6 2 5 7 3 4 5 8 1 2 3 4 5 6 7 8 9 10
输出
Yes Yes Yes Yes Yes Yes Yes Yes No No
说明
一共10总物质有第3,4,5,8 四种原料
查询每一种是否可以通过反应得到
首先通过3可以分解得到1 2
然后4 5合成6
2 5合成7
于是除了9 10都可以得到
思路:存边的时侯用(a, b, c)代表a需要在b存在时能到达c,b为0则不需要额外条件,建图完毕。bfs时若遍历到a需要借助b到达c但b还没出现的情况,则将c加入到set[b]/vector[b]里,在之后如果b
诞生时,则将b集合里的所有元素都诞生出。时空复杂度都是线性。
#include <iostream> #include <fstream> #include <sstream> #include <cstdlib> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <set> #include <map> #include <list> #include <iomanip> #include <cctype> #include <cassert> #include <bitset> #include <ctime> using namespace std; #define pau system("pause") #define ll long long #define pii pair<int, int> #define pb push_back #define mp make_pair #define clr(a, x) memset(a, x, sizeof(a)) const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const double EPS = 1e-9; int k, n, m, q; struct edge { int b, v; edge () {} edge (int b, int v) : b(b), v(v) {} }; vector<edge> E[100015]; set<int> ss[100015]; queue<int> que; bool vis[100015], exist[100015]; void born(int x) { if (exist[x]) { return; } exist[x] = 1; que.push(x); for (set<int>::iterator it = ss[x].begin(); it != ss[x].end(); ++it) { int y = *it; born(y); } ss[x].clear(); } int main() { scanf("%d%d%d%d", &k, &n, &m, &q); for (int i = 1; i <= n; ++i) { int a, b, c; scanf("%d%d%d", &a, &b, &c); E[a].pb(edge(b, c)); E[b].pb(edge(a, c)); E[c].pb(edge(0, a)); E[c].pb(edge(0, b)); } for (int i = 1; i <= m; ++i) { int x; scanf("%d", &x); que.push(x); exist[x] = 1; } while (que.size()) { int x = que.front(); que.pop(); if (vis[x]) continue; vis[x] = 1; for (int i = 0; i < E[x].size(); ++i) { int b = E[x][i].b; int v = E[x][i].v; if (!b) { born(v); } else { if (exist[b]) { born(v); } else { if (!exist[v]) { ss[b].insert(v); } } } } } while (q--) { int x; scanf("%d", &x); puts(exist[x] ? "Yes" : "No"); } return 0; }