P3916 图的遍历

题目链接: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 }

 

posted @ 2022-04-14 19:03  TFLSNOI  阅读(47)  评论(0编辑  收藏  举报