<题目链接>
题目大意:
给定$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<<' '; }