《洛谷深入浅出基础篇》P3916 图的遍历——逆向搜索
最佳答案 问答题库968位专家为你答疑解惑
上链接:
P3916 图的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://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,则说明没有这样的路)(如果一个点不能到达比他更大的点,那么这个点能到达的最大点为它本身)
起点\终点123410100200013000040010然后来一个循环,循环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] << ' ';}
}
99%的人还看了
相似问题
- pandas定位选取某列某指标最大值所在的行记录,比如月底
- java中基本数据类型的最大值最小值理解
- LeetCode Hot100之十:239.滑动窗口最大值
- 239.滑动窗口的最大值
- 【踩坑及思考】浏览器存储 cookie 最大值超过 4kb,或 http 头 cookie 超过限制值
- 寻找二维数组的最大值和对应下标 | C语言代码
- 【蓝桥杯选拔赛真题08】C++最大值最小值平均值 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析
- python:逐像素处理遥感数据时间序列数据(求时间序列最大值、最大值所对应的索引、最大值所在的时间)
- 面试算法44:二叉树中每层的最大值
- 【Python 千题 —— 基础篇】列表最大值
猜你感兴趣
版权申明
本文"《洛谷深入浅出基础篇》P3916 图的遍历——逆向搜索":http://eshow365.cn/6-41608-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: gitlab 实战
- 下一篇: Smart Tomcat的使用