zoukankan      html  css  js  c++  java
  • 【NOI2015】程序自动分析

    https://www.luogu.org/problem/show?pid=1955

    并查集+离散化。

    先执行所有x=y问题,即合并x和y。

    再依次执行所有x!=y问题,即查询x和y是否处于同一集合。如果是,则有x=y且x!=y,不满足条件。

    如果所有的x!=y都得到满足,这组数据就可以满足。

    注意到i,j范围为[1,1e9],并查集数组开不了这么大的范围。又注意到n范围只有[1,1e5],考虑离散化。

    先读入所有出现的数字,存到一个数组,然后排序并去重。之后操作用到的数字都在这个数组进行二分查找。

    时间复杂度O(nlogn)。

    注意的坑:

    • 最多有n个操作,每个操作有两个数字,所以并查集的大小应该是n*2。
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #define maxn 100005 * 2 // n个操作,每个操作两个数,最多出现n*2个数
    using namespace std;
    typedef unsigned long long ullint;
    namespace djs
    {
    int parent[maxn];
    inline void init()
    {
        for (int i = 0; i < maxn; i++)
            parent[i] = -1;
    }
    inline int find(int x)
    {
        if (parent[x] < 0)
            return x;
        else
            return parent[x] = find(parent[x]);
    }
    inline void merge(int x, int y)
    {
        x = find(x);
        y = find(y);
        if (x == y)
            return;
        else
        {
            //令x为rank更大的,即parent值更小的
            if (parent[x] > parent[y])
                swap(x, y);
            parent[x] += parent[y];
            parent[y] = x;
        }
    }
    inline bool is_related(int x, int y)
    {
        return find(x) == find(y);
    }
    }
    typedef pair<ullint, ullint> query;
    vector<query> q, m;                  // 暂存查询与合并操作
    vector<ullint> data;                 // 存储读入的所有数据
    vector<ullint>::iterator unique_end; // 去重后的数据的尾后迭代器
    inline int get_pos(ullint v)         // 二分查找v在data所处的位置
    {
        return lower_bound(data.begin(), unique_end, v) - data.begin();
    }
    int main()
    {
        ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while (t--)
        {
            int n;
            cin >> n;
            djs::init();
            m.clear();
            q.clear();
            data.clear();
    
            ullint a, b, c;
            for (int i = 0; i < n; i++)
            {
                cin >> a >> b >> c;
                data.push_back(a);
                data.push_back(b);
                switch (c)
                {
                case 1:
                    m.push_back(make_pair(a, b));
                    break;
    
                case 0:
                    q.push_back(make_pair(a, b));
                    break;
                }
            }
    
            //离散化
            sort(data.begin(), data.end());
            unique_end = unique(data.begin(), data.end());
    
            //合并
            for (int i = 0; i < m.size(); i++)
                djs::merge(get_pos(m[i].first), get_pos(m[i].second));
    
            //查询
            bool yes = true;
            for (int i = 0; i < q.size(); i++)
            {
                if (djs::is_related(get_pos(q[i].first), get_pos(q[i].second)))
                {
                    yes = false;
                    break;
                }
            }
            if (yes)
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
        }
        return 0;
    }
  • 相关阅读:
    1869六度分离
    hdu 2066 一个人的旅行
    HDU1424搬寝室
    poj 1511 Invitation Cards
    hdu 3999The order of a Tree
    hdu 2680 Choose the best route
    Hdu 3117 Fibonacci Numbers
    hdu 2962 Trucking
    钽电容黑色和黄色的区别
    ALTER FPGA通过软件设置上拉(转)
  • 原文地址:https://www.cnblogs.com/ssttkkl/p/7105772.html
Copyright © 2011-2022 走看看