题目链接:https://www.luogu.com.cn/problem/P3916
链式前向星详细教程:https://www.bilibili.com/video/BV13r4y1X7a4/?spm_id_from=333.788
1 #include<bits/stdc++.h> 2 const int MaxN=1e5+10; 3 const int MaxM=1e5+10; 4 using namespace std; 5 struct e{ 6 int to, next; 7 }edge[MaxM]; 8 int n, m, cnt, head[MaxN], ans[MaxN]; 9 10 void add(int u, int v) 11 { 12 cnt++; 13 edge[cnt].to=v; 14 edge[cnt].next=head[u]; 15 head[u]=cnt; 16 } 17 void dfs(int now, int st) 18 { 19 if(ans[now])//因为我们是倒着来的,这个点已经被遍历到过了,说明后边的点肯定能走到他,而我们遍历的顺序又是反着来的,所以后边的节点一定比他的大,则这个点所能到的最大值就不用再更新了。相应的如果之前没有点能走到他那么就需要遍历他之前的点,来寻找他的祖先。 20 return; 21 ans[now]=st; 22 for(int i=head[now]; i; i=edge[i].next) 23 { 24 int nxt=edge[i].to; 25 if(!ans[nxt]) 26 dfs(nxt, st); 27 } 28 } 29 int main() 30 { 31 cin>>n>>m; 32 for(int i=1; i<=m; i++) 33 { 34 int u, v; 35 cin>>u>>v; 36 add(v, u); //逆向存储 37 } 38 // for(int i=1; i<=n; i++) 39 // { 40 // cout<<i<<":"; 41 // for(int j=head[i]; j; j=edge[j].next) 42 // cout<<edge[j].to<<" "; 43 // cout<<endl; 44 // } 45 for(int i=n; i>=1; i--) 46 dfs(i,i); 47 for(int i=1; i<=n; i++) 48 cout<<ans[i]<<" "; 49 50 return 0; 51 }