#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int low[4060],dfn[4060],head[4060],stk[4060],id[4060],ans[4060],c[4060][4060],flag[4040];
int to[500050],Next[500050],tot,n,top,dfs_clock,num;
void add_edge(int u,int v){
to[++tot]=v;
Next[tot]=head[u];
head[u]=tot;
}
void tarjan(int u){
low[u]=dfn[u]=++dfs_clock;
stk[++top]=u;flag[u]=1;
for(int i=head[u];i;i=Next[i]){
if(dfn[to[i]]==0){
tarjan(to[i]);
low[u]=min(low[u],low[to[i]]);
}else if(flag[to[i]])
low[u]=min(low[u],low[to[i]]);
}
if(low[u]==dfn[u]){
num++;
while(stk[top]!=u){
flag[stk[top]]=0;
id[stk[top]]=num;
top--;
}
flag[u]=0;
id[u]=num;
top--;
}
}
int main(){
while(scanf("%d",&n) == 1){
num=top=tot=dfs_clock=0;
for(int i=1;i<=2*n;i++)
head[i]=dfn[i]=low[i]=0;
for(int i=1;i<=n;i++){
scanf("%d",&c[i][0]);
for(int j=1;j<=c[i][0];j++){
scanf("%d",&c[i][j]);
add_edge(i,c[i][j]+n);
}
}
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
add_edge(t+n,i);
}
for(int i=1;i<=n;i++)
if(dfn[i]==0)
tarjan(i);
for(int i=1;i<=n;i++){
int cnt=0;
for(int j=1;j<=c[i][0];j++)
if(id[i]==id[c[i][j]+n])
ans[++cnt]=c[i][j];
sort(ans+1,ans+cnt+1);
printf("%d ",cnt);
for(int j=1;j<cnt;j++)
printf("%d ",ans[j]);
printf("%d\n",ans[cnt]);
}
}
}
uvalive 2966 求一个二分图 所有的完美匹配
最新推荐文章于 2019-10-01 10:53:11 发布