参考:http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=2000+5;
const int M=205000;
bool line[N][N],instack[N*2];
int n, tot, dep, top, color, head[N+N], low[N+N], depth[N+N], c[N+N], stack[N+N], Next[M], to[M];
vector<int> ans;
void addedge(int u,int v)
{
to[tot]=v;
Next[tot]=head[u];
head[u]=tot++;
}
void dfs(int u,int &dep)
{
int p,x;
depth[u]=low[u]=dep++;
stack[++top]=u;
instack[u]=true;
for(p=head[u];p!=-1;p=Next[p])
{
if(depth[to[p]]==-1)
{
dfs(to[p],dep);
low[u]=min(low[u],low[to[p]]);
}
else if(instack[to[p]])
low[u]=min(low[u],depth[to[p]]);
}
if(low[u]==depth[u])
{
while(top)
{
x=stack[top--];
instack[x]=false;
c[x]=color;
if(x==u) break;
}
color++;
}
}
int main()
{
while(~scanf("%d",&n))
{
memset(line,false,sizeof(line));
memset(head,-1,sizeof(head));
tot=0;
for(int i=1;i<=n;i++)
{
int m,x;
scanf("%d",&m);
while(m--)
{
scanf("%d",&x);
line[i][x]=true;
addedge(i,x+n);
}
}
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
addedge(x+n,i);
}
memset(depth,-1,sizeof(depth));
memset(c,-1,sizeof(c));
memset(instack,false,sizeof(instack));
dep=top=color=0;
for(int i=1;i<=n;i++){
if(depth[i]==-1) dfs(i,dep);
}
for(int i=1;i<=n;i++){
ans.clear();
for(int j=n+1;j<=2*n;j++)
if(line[i][j-n]&&c[j]==c[i])
{ans.push_back(j-n);}
printf("%d",(int)ans.size());
for(int j=0;j<ans.size();j++) printf(" %d",ans[j]);printf("\n");
}
}
return 0;
}