链接: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都可以得到
我怕超时就用了向量
1 #include <iostream> 2 #include <cstring> 3 #include <string> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 //const double pi = acos(-1), e = exp(1); 10 vector<int>a[100005]; 11 bool v[100005]; 12 bool ff[100005]; 13 void broad(int x)//如果x可以,那么x分解的都可以 14 { 15 int i; 16 ff[x] = 1; 17 for (i = 0; i<a[x].size(); i++) 18 { 19 int t1 = a[x].at(i); 20 if (v[t1] == 0) 21 { 22 v[t1] = 1; 23 if (a[t1].size() >= 2 && ff[t1] == 0) 24 { 25 broad(t1); 26 } 27 } 28 } 29 } 30 bool bb(int x)//如果x不可以,那么查看合成它的行不行 31 { 32 int i; 33 for (i = 0; i < a[x].size(); i=i+2) 34 { 35 int t1 = a[x].at(i); 36 int t2 = a[x].at(i + 1); 37 if (v[t1] == 1 && v[t2] == 1) 38 { 39 v[x] = 1; 40 if(a[x].size()>2) broad(x); 41 return 1; 42 } 43 } 44 return 0; 45 } 46 int main() 47 { 48 int k, n, m, q; 49 int mm = -inf; 50 int mi = inf; 51 cin >> k >> n >> m >> q; 52 memset(v, 0, sizeof(v)); 53 memset(ff, 0, sizeof(ff)); 54 int i; 55 int x, y, z; 56 for (i = 1; i <= 10005; i++) a[i].clear(); 57 for (i = 1; i <= n; i++) 58 { 59 cin >> x >> y >> z; 60 if (x > mm) mm = x; 61 if (x < mi) mi = x; 62 if (y > mm) mm = y; 63 if (y < mi) mi = y; 64 if (z > mm) mm = z; 65 if (z < mi) mi = z; 66 67 a[z].push_back(x); 68 a[z].push_back(y); 69 } 70 int p; 71 for (p = 1; p <= m; p++) 72 { 73 cin >> x; 74 v[x] = 1; 75 if (a[x].size()>=2&&ff[x] == 0) 76 { 77 broad(x);//如果x可以,那么x分解的都可以 78 } 79 } 80 bool up = 1; 81 while (up)//查看合成它的 82 { 83 up = 0; 84 for (i = mi; i <= mm; i++) 85 { 86 if (v[i]==0&&a[i].size() >= 2) 87 { 88 bool f ; 89 f = bb(i); 90 if (f) up = 1; 91 } 92 } 93 } 94 for (i = 1; i <= q; i++) 95 { 96 cin >> x; 97 if (v[x] == 1) cout << "Yes" << endl; 98 else cout << "No" << endl; 99 } 100 return 0; 101 }
别人的代码更简单,不用向量也可以,直接暴力
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 int main() 6 { 7 ios::sync_with_stdio(false); 8 cin.tie(0); 9 10 int k, n, m, q; 11 cin >> k >> n >> m >> q; 12 bool book[k + 1]; 13 memset(book, false, sizeof(bool) * (k + 1)); 14 15 int first1[n], first2[n], second[n]; 16 for (int i = 0; i < n; ++i) 17 cin >> first1[i] >> first2[i] >> second[i]; 18 19 for (int i = 0; i < m; ++i) 20 { 21 int t; 22 cin >> t; 23 book[t] = true; 24 } 25 26 bool flag = true; 27 while (flag) 28 { 29 flag = false; 30 for (int i = 0; i < n; ++i) 31 { 32 if (book[first1[i]] && book[first2[i]] && !book[second[i]]) 33 { 34 book[second[i]] = true; 35 flag = true; 36 } 37 if (book[second[i]] && (!book[first1[i]] || !book[first2[i]])) 38 { 39 book[first1[i]] = true; 40 book[first2[i]] = true; 41 flag = true; 42 } 43 } 44 } 45 46 for (int i = 0; i < q; ++i) 47 { 48 int t; 49 cin >> t; 50 cout << (book[t] ? "Yes" : "No") << endl; 51 } 52 53 return 0; 54 }