1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include <iostream> #include <cstring> #include <algorithm>
using namespace std; const int N = 4e3+5; const int M = 2e5 + N;
struct { int v,next; } edge[M]; int head[N],low[N],dfn[N],sta[N],belong[N],ans[N]; bool instack[N]; int g,cnt,top,scc;
int n;
void add(int u,int v) { edge[g].v = v; edge[g].next = head[u]; head[u] = g++; }
void init() { g = cnt = top = scc = 0; memset( head,-1,sizeof head); memset( dfn, 0,sizeof dfn); memset(instack, 0,sizeof instack); }
void tarjan(int u) { dfn[u] = low[u] = ++cnt; sta[++top] = u; instack[u] = 1; for (int i=head[u]; i!=-1;i=edge[i].next) { int to = edge[i].v; if (!dfn[to]) { tarjan(to); low[u] = min(low[u],low[to]); } else if (instack[to]) low[u] = min(low[u],dfn[to]); } if (low[u] == dfn[u]) { scc++; int to; do { to = sta[top--]; instack[to] = 0; belong[to] = scc; } while(u != to); } }
void solve() { for (int u=1; u<=n; ++u) { int count = 0; for (int i=head[u]; i!=-1; i=edge[i].next) { int to = edge[i].v; if (belong[u] == belong[to]) ans[count++] = to-n; } sort(ans,ans+count); printf("%d",count); for (int i=0; i<count; ++i) printf(" %d",ans[i]); printf("\n"); } }
int main() { freopen("1.in","r",stdin); while (scanf("%d",&n) != EOF) { init(); for (int i=1; i<=n; ++i) { int k; scanf("%d",&k); while (k--) { int v; scanf("%d",&v); add(i,v+n); } } for (int i=1; i<=n; ++i) { int v; scanf("%d",&v); add(v+n,i); } for (int i=1; i<=2*n; ++i) if (!dfn[i]) tarjan(i); solve(); } return 0; }
|