- Quiz
- AC
- 解説
- パット見でトポロジカルソートっぽい。サイクルを見つけたら-1にすればいいと思うのだがそれは罠で、不要な講義でサイクルができていてもそれは-1ではない
- トポロジカルソートっぽい時はdfsで解けることが多い
- 講義の依存関係をどちらかの方向で有効辺にする発想は普通で、今回はaを取った後にしかbが取れない時、b->aの方向に辺を貼る
- editorialの通り、不要なサイクルを無視するために、必須講義を始点としてdfsする
void dfs(int u) {
if (color[u] == 0) {
color[u] = 1;
for (int to: g[u])
dfs(to);
color[u] = 2;
ord.push_back(u);
} else if (color[u] == 1)
cycle = true;
}
- 解説つづき
- このように未達部分をcolor=0, 今回のdfsで訪れた位置をcolor=1, 終わったらcolor=2とすると上手くいく
- 「うまいな~」と思う。3色dfsと名付けよう
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
ll N,K;
cin>>N>>K;
VI S(K);
rep(i,K){
cin>>S[i];
S[i]--;
}
VV G(N);
rep(i,N){
ll n;cin>>n;
while(n--){
ll a;cin>>a;a--;
G[i].push_back(a);
}
}
VI color(N);
VI ord;
bool cycle=false;
function<void(ll)> dfs = [&](ll u){
if(color[u]==0){
color[u]=1;
for(ll to : G[u]){
dfs(to);
}
ord.push_back(u);
color[u]=2;
}else if(color[u]==1){
cycle = true;
}
};
for(ll s : S) dfs(s);
if(cycle){
p(-1);return 0;
}
p(SZ(ord));
print_vector(ord,1);
return 0;
}