题目:

图的遍历

题目描述

给出 $N$ 个点,$M$ 条边的有向图,对于每个点 $v$,求 $A(v)$ 表示从点 $v$ 出发,能到达的编号最大的点。

输入格式

第 $1$ 行 $2$ 个整数 $N,M$,表示点数和边数。

接下来 $M$ 行,每行 $2$ 个整数 $U_i,V_i$,表示边 $(U_i,V_i)$。点用 $1,2,\dots,N$ 编号。

输出格式

一行 $N$ 个整数 $A(1),A(2),\dots,A(N)$。

样例 #1

样例输入 #1

1
2
3
4
4 3
1 2
2 4
4 3

样例输出 #1

1
4 4 3 4

提示

  • 对于 $60\%$ 的数据,$1 \leq N,M \leq 10^3$。
  • 对于 $100\%$ 的数据,$1 \leq N,M \leq 10^5$。

代码:
$

include

using namespace std;
const int maxn = 100001;
int m,n;
vectorl[maxn];
bool vis[maxn];
int result[maxn];
void dfs(int z,int a){
vis[z] = true;//a表示一条路的最大值,将这条路上所有的点的结果全写为a
result[z] = a;
for(int i = 0; i < l[z].size(); i++){
if(!vis[l[z][i]]){
dfs(l[z][i],a);
}
}
}
int main(){
cin>>n>>m;
for(int i = 0; i < m; i++){
int a,b;
cin>>a>>b;
l[b].push_back(a);
}
for(int i = n; i >= 1; i—){
if(!vis[i]){
dfs(i,i);//确保遍历过每个点
}
}
for(int i = 1; i <= n; i++){
cout<<result[i]<<” “;
}
}
核心思想:倒着访问图