强连通分量
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn=5000; vector<int>G[maxn]; vector<int>FG[maxn]; vector<int>Edge[maxn]; int flag[maxn],dfn[maxn],Belong[maxn]; int N,t,to,Time,Block; struct Point { int id, dfn; } point[maxn]; bool cmp(const Point&a, const Point&b) { return a.dfn>b.dfn; } void init() { for(int i=0; i<maxn; i++) G[i].clear(); for(int i=0; i<maxn; i++) FG[i].clear(); for(int i=0; i<maxn; i++) Edge[i].clear(); memset(flag,0,sizeof(flag)); memset(dfn,0,sizeof(dfn)); memset(Belong,0,sizeof(Belong)); Time=0,Block=0; } void dfs(int now) { flag[now]=1; for(int i=0; i<G[now].size(); i++) if(!flag[G[now][i]]) dfs(G[now][i]); Time++; dfn[now]=Time; } void Dfs(int now) { Belong[now] = Block; for (int i = 0; i<FG[now].size(); i++) if (!Belong[FG[now][i]]) Dfs(FG[now][i]); } int main() { while(~scanf("%d",&N)) { init(); for(int i=1; i<=N; i++) { scanf("%d",&t); while(t--) { scanf("%d",&to); G[i].push_back(to+N); FG[to+N].push_back(i); Edge[i].push_back(to); } } for(int i=1; i<=N; i++) { scanf("%d",&t); G[t+N].push_back(i); FG[i].push_back(t+N); } for (int i=1; i<=2*N; i++) if(!dfn[i]) dfs(i); for (int i=0; i<2*N; i++) point[i].id =i+1,point[i].dfn=dfn[i+1]; sort(point, point + N, cmp); for (int i = 0; i<2*N; i++) if (!Belong[point[i].id]) Block++, Dfs(point[i].id); int TOT; int Cun[maxn]; for(int i=1; i<=N; i++) { TOT=0; sort(Edge[i].begin(),Edge[i].end()); for(int j=0; j<Edge[i].size(); j++) { if(Belong[i]==Belong[Edge[i][j]+N]) { Cun[TOT]=Edge[i][j]; TOT++; } } printf("%d",TOT); for(int x=0; x<TOT; x++) printf(" %d",Cun[x]); printf(" "); } } return 0; }