洛谷题单指南-图的基本应用-P3916 图的遍历
原题链接:https://www.luogu.com.cn/problem/P3916
题意解读:寻找每个点所能到达的最大的点。
解题思路:
直观上,可以依次从每个点开始DFS搜索,记录经过的最大点,复杂度是O(n^2)级别,会超时。
可以换一种角度,既然要找每个点可以达到的最大值,那么可以反向建图,从最大值出发,所经过的点能达到的最大值就是起点。
具体来说:
1、反向建图
2、从最大值开始依次选取n...1,作为起点
3、如果该点没有访问过,从起点dfs,经过的所有点对应的答案都是该起点值
注意:dfs过程中也仅搜索没有访问过的节点
100分代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
vector<int> g[N];
int ans[N];
int n, m, u, v;
void dfs(int u, int value)
{
ans[u] = value;
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if(!ans[v]) dfs(v, value);
}
}
int main()
{
cin >> n >> m;
while(m--)
{
cin >> u >> v;
g[v].push_back(u); //反向建图
}
for(int i = n; i >= 1; i--)
{
if(!ans[i]) dfs(i, i); //从较大的点开始搜索,搜到的所有点能到达最大的点就是起点
}
for(int i = 1; i <= n; i++) cout << ans[i] << " ";
return 0;
}