题意:国王有n个儿子,另有n个妹子,儿子要把妹子,每个儿子都自己喜欢的妹子们,问每个儿子可以怎样选择,然后不影响其他儿子把妹。
思路:先从儿子到喜欢的妹子建立有向边,然后根据男巫给的配对方案从妹子到儿子建立有向边,然后计算强连通分量,然后对于每个儿子可以选择的就是和自己在一个强连通分量里的喜欢的妹子。
看wwj的博客,见他吐槽国王儿子太多,我也吐槽下。2000个儿子!!!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
stack<int>st;
int n,m,bnum,scnum,fst[4005],next[300005],node[300005];
int num,low[4005],dfn[4005],d[4005],ans[4005],anum;
bool inst[4005];
//inline void RD(int &ret)
//{
// char c;
// do
// {
// c=getchar();
// }
// while(c<'0'||c>'9');
// ret=c-'0';
// while((c=getchar())>='0'&&c<='9')ret=ret*10+(c-'0');
//}
//
//inline void OT(int a)
//{
// if(a>= 10)OT(a/10);
// putchar(a%10+'0');
//}
int in()
{
char ch;
int a=0;
while((ch=getchar())==' '||ch=='\n');
a += ch - '0';
while((ch=getchar())!=' '&&ch!='\n')
{
a*=10;
a+=ch-'0';
}
return a;
}
void out(int a)
{
if(a>=10)out(a/10);
putchar(a%10+'0');
}
void init()
{
int u,v;
num=bnum=scnum=0;
memset(fst,-1,sizeof(fst));
memset(dfn,0,sizeof(dfn));
memset(inst,0,sizeof(inst));
for(int i=1; i<=n; i++)
{
//scanf("%d",&m);
//RD(m);
m=in();
for(int j=0; j<m; j++)
{
//scanf("%d",&v);
//RD(v);
v=in();
v+=n;
next[++bnum]=fst[i];
fst[i]=bnum;
node[bnum]=v;
}
}
for(int i=1; i<=n; i++)
{
//scanf("%d",&v);
//RD(v);
v=in();
v+=n;
next[++bnum]=fst[v];
fst[v]=bnum;
node[bnum]=i;
}
}
void tarjan(int u)
{
int v;
dfn[u]=low[u]=++num;
st.push(u);
inst[u]=1;
for(int i=fst[u]; i!=-1; i=next[i])
{
v=node[i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(inst[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
scnum++;
do
{
v=st.top();
st.pop();
inst[v]=0;
d[v]=scnum;
}
while(u!=v);
}
}
void solve()
{
for(int i=1; i<=n; i++)
{
if(!dfn[i])tarjan(i);
}
for(int i=1; i<=n; i++)
{
anum=0;
for(int j=fst[i]; j!=-1; j=next[j])
{
int v=node[j];
if(d[i]==d[v])
{
ans[anum++]=v-n;
}
}
sort(ans,ans+anum);
//printf("%d",anum);
out(anum);
for(int j=0; j<anum; j++)//printf(" %d",ans[j]);
{
//printf(" ");
putchar(' ');
out(ans[j]);
}
//printf("\n");
putchar('\n');
}
}
int main()
{
//scanf("%d",&n);
//RD(n);
n=in();
init();
solve();
return 0;
}