题意
给定你 $n$ 本书,在读第 $i$ 本书的时候,必须先读完若干本书(怎么看着像拓扑排序),现在要求想读第 $1$ 本书之前,要先按顺序读完哪些书?
思路
很显然,若读完第 $1$ 本书之前要先读完 $a_1,a_2,…..a_n$,那么又考虑子部分,即读 $a_1,a_2….a_n$ 又先需要读完哪些书。
显然可以用 dfs 搞定,深搜读当前书要先读哪些书,返回的时候加入 $ans$ 数组记录,并用 $vis$ 数组标记,最后输出 $ans$ 即可。
代码
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
| #include<bits/stdc++.h> #define int long long #define endl "\n" using namespace std; template<typename P> inline void read(P &x){ P res=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ res=res*10+ch-'0'; ch=getchar(); } x=res*f; } int n; const int Max=200010; struct egde{ int to,nxt; }e[Max<<1]; int head[Max],cnt=0; void add(int u,int v){ e[++cnt].to=v; e[cnt].nxt=head[u]; head[u]=cnt; } int c[Max]; vector<int> a[Max]; vector<int> ans; bool vis[Max]; void dfs(int u,int fa){ vis[u]=1; for(int i=head[u];i;i=e[i].nxt){ int to=e[i].to; if(!vis[to] && to!=fa){ dfs(to,u); } } ans.push_back(u); } signed main(){ read(n); for(int i=1;i<=n;++i){ read(c[i]); int x; for(int j=1;j<=c[i];++j){ read(x); a[i].push_back(x); add(i,x); } } for(int i=0;i<c[1];++i){ int p=a[1][i]; if(!vis[p]){ dfs(p,0); } } for(int i=0;i<ans.size();++i){ cout<<ans[i]<<' '; } cout<<endl; return 0; }
|