P3916 图的遍历

P3916 图的遍历
题目来源-洛谷

题意

有向图中,找出每个节点能访问到的最大的节点

思路

  • 每个节点的最大节点,不是最长距离,如果是每个节点都用dfs去找最大值,显然1e6*1e6 超时了,只能60分
  • 从第一个节点开始遍历,要超时,逆着思路想,求最大节点,那么从最大的节点开始遍历,逆着看哪些点能到达该节点,立刻标记,且从大的节点来看,后面的节点不可能有比该节点更大的点(哪怕有,也是被访问的-比当前更大的节点),因此只需要标记走过的节点,就可以不必再重复遍历,节省时间开销
  • 因此存图时需要逆向存

数据约束

注意数组长度即可

参考代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+5;
void dfs(int k,int maxk);//从节点K开始搜索 
int m,n;//n个点m条边 
vector<int> p[MAXN];//邻接表存图 
bool f[MAXN] = {false};
int ans[MAXN] ;//存结果 
int main(){ 
	cin>>n>>m;
	int x,y;
	for(int i=0;i<m;i++){
		cin>>x>>y; //x 能到 y 
		p[y].push_back(x);//反向存图 
	} 
	//	查看储存的数据是否正确 
//	for(int i=1;i<=n;i++){
//		for(int j=0;j<p[i].size();j++){
//			cout<<p[i][j]<<" "; 
//		} 
//		cout<<endl;
//	}
	for(int i=n;i>0;i--){
		dfs(i,i) ;//从最大的点开始搜索 
	} 
	for(int i=1;i<=n;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}
void dfs(int k,int maxk){
	if(f[k]) return;
	ans[k] = maxk;
	f[k] = true;//如果此处不标记,但是是第一个遍历到节点就必须记得处理 
	for(int i=0;i<p[k].size();i++){
		if(!f[p[k][i]]){ //没被访问过则访问 
			dfs(p[k][i],maxk);
		//	f[p[k][i]] = true;//在开头赋值的地方标记后就不用重复标记 
		}
	}
	return ;
}
相关推荐
凌辰揽月12 分钟前
Web后端基础(基础知识)
java·开发语言·前端·数据库·学习·算法
lifallen18 分钟前
深入浅出 Arrays.sort(DualPivotQuicksort):如何结合快排、归并、堆排序和插入排序
java·开发语言·数据结构·算法·排序算法
jingfeng51418 分钟前
数据结构排序
数据结构·算法·排序算法
能工智人小辰44 分钟前
Codeforces Round 509 (Div. 2) C. Coffee Break
c语言·c++·算法
kingmax542120081 小时前
CCF GESP202503 Grade4-B4263 [GESP202503 四级] 荒地开垦
数据结构·算法
岁忧1 小时前
LeetCode 高频 SQL 50 题(基础版)之 【高级字符串函数 / 正则表达式 / 子句】· 上
sql·算法·leetcode
eachin_z2 小时前
力扣刷题(第四十九天)
算法·leetcode·职场和发展
闻缺陷则喜何志丹2 小时前
【强连通分量 缩点 拓扑排序】P3387 【模板】缩点|普及+
c++·算法·拓扑排序·洛谷·强连通分量·缩点
机器学习之心2 小时前
机器学习用于算法交易(Matlab实现)
算法·机器学习·matlab
AL流云。2 小时前
【优选算法】C++滑动窗口
数据结构·c++·算法