zoukankan      html  css  js  c++  java
  • [CF1463E] Plan of Lectures

    [CF1463E] Plan of Lectures - 拓扑排序,并查集

    Description

    构造一个 1..n 的排列,有一些限制:指定了一些 (ai,i) 要求 ai 出现在 i 的前面,指定了一些 (i,j) 要求 i 一定在 j 之前一个位置

    Solution

    先考虑第二类条件,用类似并查集的方法来串串,最后我们把一个点往后几个固定的点都找出来,同时判断是否有环路

    接下来缩点(选取链头作为代表点)然后跑拓扑排序

    跑完拓扑以后,我们把得到的序列展开(缩点还原),然后检查一遍所有条件是否满足即可

    (第一遍写的时候把两种条件看反了)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    int n, m;
    int fa[N];
    pair<int, int> e[N];
    vector<int> toposeq;
    vector<int> g[N];
    int vis[N], ind[N];
    list<int> ls[N];
    vector<int> seq;
    int a[N];
    
    int find(int p)
    {
        return p == fa[p] ? p : fa[p] = find(fa[p]);
    }
    
    void dfs(int p)
    {
        vis[p] = 1;
        for (auto q : g[p])
            if (vis[q] == 0)
            {
                dfs(q);
            }
        toposeq.push_back(p);
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            fa[i] = i, ls[i].push_back(i);
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
        }
        for (int i = 1; i <= m; i++)
        {
            int u, v;
            cin >> u >> v;
            int p = find(u), q = find(v);
            if (p == q)
            {
                cout << 0 << endl;
                return 0;
            }
            else
            {
                fa[q] = p;
                ls[p].splice(ls[p].end(), ls[q]);
            }
        }
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == 0)
                continue;
            int u = a[i], v = i;
            e[i] = {u, v};
            if (find(u) == find(v))
                continue;
            g[find(u)].push_back(find(v));
            ind[find(v)]++;
        }
        for (int i = 1; i <= n; i++)
            if (ind[i] == 0 && find(i) == i)
                dfs(i);
        reverse(toposeq.begin(), toposeq.end());
        for (auto p : toposeq)
        {
            for (auto i : ls[p])
            {
                seq.push_back(i);
            }
        }
        vector<int> inv(n + 2);
        for (int i = 0; i < seq.size(); i++)
            inv[seq[i]] = i;
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == 0)
                continue;
            int u = a[i], v = i;
            if (inv[v] < inv[u])
            {
                cout << 0 << endl;
                return 0;
            }
        }
        if (seq.size() == 0)
        {
            cout << 0 << endl;
            return 0;
        }
        for (int i = 0; i < seq.size(); i++)
            cout << seq[i] << " ";
        cout << endl;
    }
    
  • 相关阅读:
    stenciljs 学习四 组件装饰器
    stenciljs 学习三 组件生命周期
    stenciljs 学习二 pwa 简单应用开发
    stenciljs ionic 团队开发的方便web 组件框架
    stenciljs 学习一 web 组件开发
    使用npm init快速创建web 应用
    adnanh webhook 框架 hook rule
    adnanh webhook 框架 hook 定义
    adnanh webhook 框架request values 说明
    adnanh webhook 框架execute-command 以及参数传递处理
  • 原文地址:https://www.cnblogs.com/mollnn/p/14474656.html
Copyright © 2011-2022 走看看