zoukankan      html  css  js  c++  java
  • [CF770C] Online Courses In BSU

    一共有 (N) 个科目,其中有 (M) 个主要科目,只要 (M) 个主要科目都通过了,那么对应主人公就可以毕业了,也就是达成了目的。现在有一个列表,表示要通过第 (i) 门课程需要先通过的科目列表。现在主人公希望得到一个通过科目的顺序,使得最终他通过最少的科目使得主人公毕业。

    Solution

    如果有环,则无解

    对于每个主科目,从这个点开始,在反图上 DFS 即可,遇到已经标记的点就退出

    输出时按照拓扑序输出

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 100005;
    
    int n,m,t1,t2,t3,s[N],tim[N],fg[N],vis[N],ind;
    vector <int> g[N];
    
    namespace scc {
        vector <int> scc[N];
        int ind,f[N],siz[N],dfn[N],low[N],vis[N],s[N],bel[N],top,tot,m;
        void dfs(int p) {
            s[++top]=p;
            dfn[p]=low[p]=++ind;
            for(int i=0;i<g[p].size();i++) {
                int q=g[p][i];
                if(!dfn[q]) dfs(q), low[p]=min(low[p],low[q]);
                else if(!bel[q]) low[p]=min(low[p],dfn[q]);
            }
            if(dfn[p]==low[p]) {
                ++tot;
                for(int i=0;i!=p;) {
                    i=s[top--];
                    bel[i]=tot;
                    scc[tot].push_back(i);
                }
            }
        }
        void solve() {
            for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
        }
    }
    
    void dfs(int p) {
        vis[p]=1;
        for(int q:g[p]) if(vis[q]==0) dfs(q);
        tim[p]=++ind;
    }
    
    int cmp(int a,int b) {
        return tim[a]<tim[b];
    }
    
    void mark(int p) {
        fg[p]=1;
        for(int q:g[p]) if(fg[q]==0) mark(q);
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>m;
        for(int i=1;i<=m;i++) {
            cin>>s[i];
        }
        for(int i=1;i<=n;i++) {
            cin>>t1;
            while(t1--) {
                cin>>t2;
                g[i].push_back(t2);
            }
        }
        scc::solve();
        int flag=0;
        for(int i=1;i<=n;i++) if(!vis[i]) dfs(i);
        for(int i=1;i<=m;i++) mark(s[i]);
        for(int i=1;i<=n;i++) if(fg[i]&&scc::scc[scc::bel[i]].size()>1)
            flag=1;
        if(flag) {
            cout<<-1;
        }
        else {
    
            vector <int> ans;
            for(int i=1;i<=n;i++) if(fg[i]) ans.push_back(i);
            sort(ans.begin(),ans.end(),cmp);
            cout<<ans.size()<<endl;
            for(int i:ans) cout<<i<<" ";
        }
    }
    
    
  • 相关阅读:
    广告术语及缩写
    run `npm audit fix` to fix them, or `npm audit` for details
    Notes:SVG(2)---各种常见图形
    Notes:SVG(1)
    Notes:indexedDB使用
    Notes: select选择框
    Notes:DOM的事件模拟
    Notes: DOM Range
    Git-Notes
    Javascript一些实用技巧
  • 原文地址:https://www.cnblogs.com/mollnn/p/12589097.html
Copyright © 2011-2022 走看看