洛谷题单指南-图的基本应用-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;
}

 

posted @ 2024-03-27 14:24  五月江城  阅读(66)  评论(0编辑  收藏  举报