图的遍历

P3916 图的遍历

题目描述

给出 \(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

4 3
1 2
2 4
4 3

输出 #1

4 4 3 4

说明/提示

  • 对于 \(60\%\) 的数据,\(1 \leq N,M \leq 10^3\)
  • 对于 \(100\%\) 的数据,\(1 \leq N,M \leq 10^5\)
    这道题问一个点能走到的最大的点是多少,我们可以反向建边,求一个点最大可以由哪个点走到
#include<iostream>
#include<vector>
using namespace std;
const int N=1e5+5;
vector<int>v[N];
int d[N];
void dfs(int x,int y){
    d[x]=y;
    for(int i=0;i<v[x].size();i++){
        if(!d[v[x][i]])dfs(v[x][i],y);//没有被更新才能递归,如果不是零,说明被之前更大的点更新了
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    while(m--){
        int x,y;
        cin>>x>>y;
        v[y].push_back(x);
    }
    for(int i=n;i>=1;i--){
        if(!d[i])dfs(i,i);//由于是从大到小遍历,如果没有比他更大的点走到,那么最大的点肯定是他本身;
    }
    for(int i=1;i<=n;i++)cout<<d[i]<<" ";
    return 0;
}
posted @ 2025-03-08 18:28  郭轩均  阅读(36)  评论(0)    收藏  举报