《洛谷深入浅出基础篇》P3916 图的遍历——逆向搜索

上链接:

P3916 图的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P3916上题干:

题目描述

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

输入格式

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

接下来 M 行,每行 2 个整数 Ui​,Vi​,表示边 (Ui​,Vi​)。点用 1,2,…,N 编号。

输出格式

一行 N 个整数A(1),A(2),…,A(N)。

输入输出样例

输入 #1复制

4 3
1 2
2 4
4 3

输出 #1复制

4 4 3 4

说明/提示

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

 我一开始的想法就是,暴力搜索,每次搜索每个点能到达的最大点。

像题目所给的数据:(这个表格的是指,是否有这样一条路可以连通某起点和某终点,边权默认为1,若边权为0,则说明没有这样的路)(如果一个点不能到达比他更大的点,那么这个点能到达的最大点为它本身)

起点\终点1234
10100
20001
30000
40010

然后来一个循环,循环n次,代表1~n个点,每个点来一遍dfs。

然后每次递归更新这个点能到达的最大值 ,直到递归到底部。

然后我悲催的发现,这样时间复杂度将是爆炸的。

因为每个点能到达的点的值都会被重复遍历很多次。

于是我们想起了高中老师经常教我们的:正难则反的思想。

我们不如让最大值自己去寻找能到达哪些点。

比如我们先让4(最大值)去找,4能到哪些点。将这些点标记为4.

然后再让次大值 3(最大值)去寻找,如果找到的点被标记过了,那么就跳过,因为被标记的点一定是上一轮dfs标记的,也就是被比3大的值所标记。

然后依次类推。

因为有了标记数组的存在,所以我们遍历的次数大大减少了。

那么这样让最大值去寻找能被哪些点到达的方法怎么找呢?我们可以反过来建边。

这样就可以从最大值出发来寻找每个它能到达的点了。

上代码:

const int N = 1e5 + 7;
const int M = 1e5 + 7;
int n, m;
int flag[N];
vector<int > p[M];

void dfs(int x, int y) {
    flag[x] = y;
    for (int i = 0; i < p[x].size(); i++) {
        if (flag[p[x][i]] == 0){
            dfs(p[x][i], y);
        }
    }
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        p[v].push_back(u);
    }
    for (int i = n; i > 0; i--)
    {
        if (flag[i] == 0)
            dfs(i, i);
    }
    for (int i = 1; i <= n; i++) {
        cout << flag[i] << ' ';
    }
}

 

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《洛谷深入浅出程序设计竞赛(基础) pdf》是一本关于程序设计竞赛基础知识的书籍,主要面向初学者。本书作者通过深入浅出的方式,以简洁清晰的语言讲解了程序设计竞赛中常见的基础知识和技巧。 该书首先介绍了算法和数据结构的基本概念,包括常见的排序算法、栈、队列、链表、树等数据结构。然后,详细讲解了常用的算法设计技巧,如贪心算法、动态规划、递归等,并通过大量的例题进行了实践演练,使读者能更好地理解和掌握这些技巧。 此外,本书还介绍了常见的编程语言和开发环境,如C++、Python和Java等,并提供了一些常用的程序调试技巧和工具,帮助读者解决实际编程过程中可能遇到的问题。 《洛谷深入浅出程序设计竞赛(基础) pdf》还包含了大量的习题和实例,供读者进行练习和巩固所学知识。同时,书中还提供了一些实战经验和竞赛技巧,帮助读者提高在程序设计竞赛中的表现。 总的来说,《洛谷深入浅出程序设计竞赛(基础) pdf》适合初学者入门,内容全面、易懂,对于想要了解程序设计竞赛基础知识和提升编程能力的人来说是一本很好的参考书。 ### 回答2: 《洛谷深入浅出程序设计竞赛(基础) pdf》是一本内容丰富、有助于初学者提高编程能力的书籍。该书主要介绍了洛谷这个在线判题系统的使用方法以及一些常见的算法和数据结构知识。 首先,书中详细介绍了洛谷这个在线判题系统的功能和使用方法。洛谷是一个非常受欢迎的在线编程平台,它提供了丰富的题目和在线编译环境,使得用户可以更加方便地练习和学习编程。书中通过简单明了的语言和文并茂的示例,向读者介绍了洛谷的登录、题目搜索、代码提交等基本操作,帮助读者迅速上手这个平台。 其次,书中系统地介绍了一些常见的算法和数据结构知识。这对于初学者来说,是非常重要的一部分。书中通过具体的例子和详细的讲解,向读者介绍了一些常见的算法,如搜索、排序和动态规划等。同时,书中还提供了一些实操编程题目,使得读者可以通过练习加深对这些算法的理解和掌握。 总的来说,《洛谷深入浅出程序设计竞赛(基础) pdf》是一本对于初学者来说非常有价值的书籍。它通过详细的介绍洛谷系统的使用方法和常见算法的讲解,帮助读者快速入门,并且提高编程能力。阅读这本书,不仅可以帮助初学者更好地了解和使用洛谷系统,还可以提供一些常见算法的思路和实践经验,对于参加编程竞赛和提升编程能力有着积极的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值