• Luogu P3916 图的遍历


    P3916 图的遍历

    题目描述

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

    输入输出格式

    输入格式:

    第1 行,2 个整数 $N,M$ 。

    接下来 $M$ 行,每行2个整数 $U_i,V_i$​ ,表示边 $(U_i,V_i)$ 。点用 $1, 2,cdots,N$ 编号。

    输出格式:

    $N$ 个整数 $A(1),A(2),cdots,A(N)$ 。

    输入输出样例

    输入样例#1:
    4 3
    1 2
    2 4
    4 3
    输出样例#1:
    4 4 3 4
    说明

    • 对于60% 的数据, $1 le N . K le 10^3$ ;

    • 对于100% 的数据, $1 le N , M le 10^5$ 。

    有部分分,那就先打个暴力。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define Edge_max 100008
    
    using namespace std;
    
    int n, m, outdgr[Edge_max], ans;
    
    bool vis[Edge_max];
    
    int u[Edge_max], v[Edge_max], first[Edge_max], next[Edge_max];
    
    void dfs(int k) {
    	ans = max(ans, k);
    	if(outdgr[k] == 0) {
    		
    		return ;
    	}
    	int s = first[k];
    	while(s != -1) {
    		if(!vis[v[s]]) {
    			vis[v[s]] = 1;
    			dfs(v[s]);
    			vis[v[s]] = 0;
    		}
    		s = next[s];
    	}	
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	memset(first, -1, sizeof(first));
    	for(int i=1; i<=m; i++) {
    		scanf("%d%d", &u[i], &v[i]);
    		next[i] = first[u[i]];
    		first[u[i]] = i;
    		outdgr[u[i]]++;
    	}
    	for(int i=1; i<=n; i++) {
    		memset(vis, 0, sizeof(vis));
    		ans = 0;
    		dfs(i);
    		printf("%d ", ans);
    	}
    }
    

      

      

     

    铛啷啷,就是这样的。

    然后我们考虑反向建边,这样就不会有后效性。

    然后把沿途经过的点都标记一遍,就$AC$了

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #define Edge_max 100008
    
    using namespace std;
    
    int n, m, ans, A[Edge_max];
    
    bool vis[Edge_max];
    
    int u[Edge_max], v[Edge_max], first[Edge_max], next[Edge_max];
    
    void dfs(int k) {
    	A[k] = max(A[k], k);
    	int s = first[k];
    	while(s != -1) {
    		if(!A[v[s]]) A[v[s]] = A[k], dfs(v[s]);
    		s = next[s];
    	}
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	memset(first, -1, sizeof(first));
    	for(int i=1; i<=m; i++) {
    		scanf("%d%d", &u[i], &v[i]);
    		swap(u[i], v[i]);
    		next[i] = first[u[i]];
    		first[u[i]] = i;
    	}
    	for(int i=n; i>=1; i--) {
    		ans = 0;
    		dfs(i);
    	}
    	for(int i=1; i<=n; i++) printf("%d ", A[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    偶对学习C#以及理解.Net平台的一些看法(二,Junior Bibliography)
    聊聊编程那些破事0.Prehistory
    偶对学习C#以及理解.Net平台的一些看法(一,Prerequisites)
    [转帖]c#.net常用函数列表
    一个编程小题目引发的思考(上)
    geoTools学习笔记001(简介)
    ArcGIS Server 10安装配置(JAVA)
    ARCGIS中label(标注)和Annotation(注记
    JSTL入门开发包详解
    基于C/S的网盘设计(JAVA) 网盘源码实现部分功能
  • 原文地址:https://www.cnblogs.com/bljfy/p/9053521.html
Copyright © 2020-2023  润新知