思路:
顯然按照他的意思建圖肯定不行。
對於u所需要先解決的v[], 建邊 u -> v[], 然後就是判斷一下每個main 課程是否在一個環裏,或者是不是他需要先修的課程在環裏,這樣子就不滿足。
然後我就很爆炸,窩很蠢地想到了Tarjan,然後就處理了一下那些強連通分量,然後就是用來判斷是不是在環裏,不滿足。
然後就是對每個main 課程 DFS搜,然後就好啦,然後智障的窩第一次發現這個拓撲排序的逆序竟然是DFS序。。。
因爲菜啊!!不會一次DFS就能判斷= =、就瞄了瞄題解。。我就不多bb了…思路基本一樣。。。但是人家的寫法。。(窩看到的時候內心是崩潰的)
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;
}
然後我的搓代碼。。(其實單組案例可以去掉那些沒必要的初化)
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<list>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const double eps = 1e-9;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int Maxn = 1e5 + 10;
int n, k;
struct Edge{
int v, nex;
}edge[Maxn<<1];
int head[Maxn], tol;
int sp[Maxn];
bool spi[Maxn];
void init(){
tol = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v){
edge[tol] = (Edge){v, head[u]}, head[u] = tol++;
}
bool flag, wa[Maxn];
int low[Maxn], dfn[Maxn];
int sta[Maxn], cnt, top, ind;
bool vis[Maxn];
int id[Maxn];
void Tarjan(int u){
if(flag) return;
low[u] = dfn[u] = ++ind;
vis[u] = true;
sta[++top] = u;
int v;
for(int i=head[u]; ~i;i=edge[i].nex){
v = edge[i].v;
if(!dfn[v]){
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]){
int temp;
int sum = 0;
bool f = false;
cnt++;
while(1){
temp = sta[top];
if(spi[temp]) f = true;
vis[temp] = false;
id[temp] = cnt;
top--;
sum++;
if(temp == u) break;
}
if(sum > 1 && f){
flag = true;
return;
}
if(sum > 1) wa[cnt] = true;
}
}
bool Judge(){
memset(wa, false, sizeof(wa));
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(vis, false, sizeof(vis));
top = cnt = top = 0;
for(int i=1;i<=n;i++){
if(flag) return false;
if(!dfn[i]) Tarjan(i);
}
if(flag) return false;
return true;
}
int ans[Maxn], ans_num;
bool used[Maxn];
void DFS(int u){
int v;
if(flag) return;
if(wa[id[u]]){
flag = true;
return;
}
used[u] = 1;
for(int i=head[u];~i;i=edge[i].nex){
v = edge[i].v;
if(vis[v] || used[v]) continue;
DFS(v);
}
if(!vis[u]){
ans[ans_num++] = u;
vis[u] = true;
}
}
void solve(){
flag = false;
if(!Judge()){
puts("-1");
// puts("aaa");
return;
}
int u;
memset(vis, false, sizeof(vis));
memset(used, false, sizeof(used));
for(int i=1;i<=k;i++){
if(flag){
puts("-1");
return;
}
u = sp[i];
if(vis[u] || used[u]) continue;
DFS(u);
}
if(flag){
puts("-1");
return;
}
printf("%d\n", ans_num);
for(int i=0;i<ans_num;i++)
{
if(i) printf(" ");
printf("%d", ans[i]);
}
}
int main(){
int m;
int u, v;
scanf("%d%d", &n, &k);
init();
memset(spi, false, sizeof(spi));
for(int i=1;i<=k;i++){
scanf("%d", &sp[i]);
spi[sp[i]] = true;
}
for(int i=1;i<=n;i++){
scanf("%d", &m);
u = i;
while(m--){
scanf("%d", &v);
add(u, v);
}
}
solve();
return 0;
}
/*
4 1
4
1 2
1 3
1 4
1 2
3 3
1 2 3
2 2 3
1 3
0
4 1
4
1 3
1 1
1 2
1 3
*/