蓝桥杯备赛 Day12.2图的遍历

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)。

  • 对于 60% 的数据,1≤N,M≤10^3。
  • 对于 100%的数据,1≤N,M≤10^5。
    #include<iostream>
    #include<vector>
    using namespace std;
    
    //本题是图的遍历(简单版)的数据加强版
    //本题数据规模较大,故图的空间和时间消耗较大,需要引入邻接表
    //另外当数据量超过1e5,建议使用scanf、printf进行IO优化
    //本题优化:反向建图,考虑较大的点能到达哪些点 
    const int N = 1e5 + 10;
    vector<int> g[N];//邻接表 
    int n, m;
    
    int cnt[N];//记录每个点能搜到的最远点 
    bool vis[N];//标记数组 
    
    //cur-当前点,  maxv-最远点 
    void dfs(int maxv, int cur) {
    	if (cnt[cur]) return;//如果cur已经记录最远点,则直接结束 
    	cnt[cur] = maxv; //记录cur的最远点maxv  cnt[3]=3  cnt[4]=4  cnt[2]=4 cnt[1]=4
    	//沿着邻接点搜索 
    	for (auto u : g[cur]) {
    		dfs(maxv, u);
    	}
    }
    
    int main() {
    	cin >> n >> m;
    
    	for (int i = 1; i <= m; i++) {
    		int u, v; scanf("%d %d", &u, &v);
    		g[v].push_back(u);//反向建图 
    	}
    
    	for (int i = n; i >= 1; i--) {
    		dfs(i, i);//针对每个最远点搜索能到达的点 
    	}
    
    	for (int i = 1; i <= n; i++) printf("%d ", cnt[i]);
    
    	return 0;
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值