Codeforces 770C Online Courses In BSU (DFS)

<题目链接>

题目大意:
给定$n$个任务,其中有$m$个主线任务,然后$n$个任务中,每个任务都有可能有一个list,表示完成这个任务之前必须要完成的任务,然后现在让你找出,完成这$m$个主线任务至少要完成的任务,输出这些任务。

解题分析:

建图的时候注意一下,所有任务向必须要在它之前完成的任务连一条有向边。遍历所有的主线任务,然后用DFS判一下环,注意$vis$状态要设3个,这样才能起到判断冲突的作用。

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
const int N = 1e5+5;
#define REP(i,s,t) for(int i=s;i<=t;i++)
vector<int>vec,ans,G[N];
int vis[N];
void dfs(int u){
    if(vis[u]==2)return;
    vis[u]=1;     //vis[u]=1表示当前完成u这个主线任务需要涉及到的点
    for(auto v:G[u]){
        if(vis[v]==1)
            puts("-1"),exit(0);
        dfs(v);
    }
    vis[u]=2;        //表示这个点已经选完了
    ans.pb(u);
}
int main(){
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n,m;cin>>n>>m;
    REP(i,1,m){
        int now;cin>>now;
        vec.pb(now);
    }
    REP(u,1,n){
        int k;cin>>k;
        while(k--){
            int v;cin>>v;
            G[u].pb(v);
        }
    }
    for(auto v:vec)dfs(v);
    cout<<ans.size()<<endl;
    for(auto v:ans)cout<<v<<' ';
}
原文地址:https://www.cnblogs.com/00isok/p/10884261.html