zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    转载:configure生成的文件(1.5.3)《深入理解Nginx》(陶辉)
    现场管理
    02 表扫描
    01 成本的含义
    16 计划稳定性与控制
    14 事务处理
    13 SELECT 以外的内容
    12 索引
    11 半联结 & 反联结
    08 分析函数
  • 原文地址:https://www.cnblogs.com/bljfy/p/9053521.html
Copyright © 2011-2022 走看看