AX. *【递归:图的遍历】有向图中点能到达的最大编号[P3916]图的遍历
*【递归:图的遍历】有向图中点能到达的最大编号[P3916]图的遍历
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
Description
【题意】图的遍历给出 $N$ 个点,$M$ 条边的有向图。对于每个点 $i$,求从点 $i$ 出发能到达的编号最大的点( 用 $A(i)$ 表示)。
【输入格式】
第 $1$ 行 $2$ 个整数 $N,M$,表示点数和边数($1 \leq N,M \leq 10^5$)。
接下来 $M$ 行,每行 $2$ 个整数 $x_i,y_i$,表示边 $(x_i,y_i)$。
【输出格式】
一行 $N$ 个整数: $A(1),A(2),\dots,A(N)$。
【样例输入】
4 3
1 2
2 4
4 3
【样例输出】
4 4 3 4
Hint
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> G[N]; //vector存图
int f[N];
void dfs(int x,int mx)
{
if(f[x]) return; //访问过
f[x]=mx;
for(auto y:G[x])//for(int i=0; i<G[x].size(); i++){ int y=G[x][i];
{
dfs(y,max(y,mx));
}
}
int main()
{
int n,m;scanf("%d%d", &n, &m);
for(int i=1,x,y; i<=m; i++)
{
scanf("%d%d", &x, &y);
G[y].push_back(x); //反向建边
}
memset(f,0,sizeof(f));
for(int i=n;i>=1;i--)dfs(i,i);
for(int i=1; i<=n; i++) printf("%d ", f[i]);
printf("\n");
return 0;
}
</p>