zoukankan      html  css  js  c++  java
  • 常州大学新生赛 I-合成反应

    链接:https://www.nowcoder.net/acm/contest/78/I
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制: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;
    }
  • 相关阅读:
    RMAN备份脚本执行遇到RMAN-03002,06091问题处理
    物化视图日志过大,手工清理
    大表添加一个字段需求
    oracle_job进程相关学习测试
    11.2.0.4单实例静默安装
    RMAN执行crosscheck archive报错ORA-19633问题处理
    df执行hang住
    应用人员反馈报错,ORA-03137: TTC protocol internal error : [12333]
    普通表分区改造_rename方式
    SQL查询oracle数据库最近备份情况
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8428274.html
Copyright © 2011-2022 走看看