打卡第五天 P3916 图的遍历

今天是我打卡第五天,做个普及/提高−题吧(#^.^#)

原题链接:图的遍历 - 洛谷

题目描述

给出 N 个点,M 条边的有向图,对于每个点 v,求 A(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% 的数据,1≤N,M≤10^3。

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

C++

#include <bits/stdc++.h>
using namespace std;
const int  maxn=1e5+10;
int vis[maxn],ans[maxn],head[maxn],cnt=0,n,m,temp=0;
struct newt{
    int to,next;
}e[maxn];
void addedge(int u,int v){
    e[cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void dfs(int u){
    vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(!vis[v])dfs(v);
    }
    ans[u]=temp;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)head[i]=-1,ans[i]=i;
    for(int i=1,a,b;i<=m;i++){
        scanf("%d%d",&a,&b);
        addedge(b,a);
    }
    for(int i=n;i>=1;i--)
    if(!vis[i]){
        temp=i;
        dfs(i);
    }
    for(int i=1;i<=n;i++)
    printf("%d%c",ans[i],i==n?'\n':' ');
    return 0;
}

Python

n,m = map(int,input().split(' '))
hash_end = {}
for i in range(1,n+1):
    hash_end[i] = set([i])
for i in range(m):
    u,v = map(int,input().split(' '))
    hash_end[v].add(u)
ans = [0]*(n+1)
visited = set()
st = n
while len(visited)!=n and st>0:
    queue = list(hash_end[st])
    while queue:
        q = queue.pop()
        if q in visited:
            continue
        ans[q] = st
        visited.add(q)
        for new in hash_end[q]:
            if new not in visited:
                queue.append(new)
    st -= 1
for i in range(1,n+1):
    print(ans[i],end=" ")

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void dfs(List<Integer>[] map, int[] dp, int start, int value) {
        if (dp[start] != 0) {
            return ;
        }
        dp[start] = value;
        for (int i = 0; i < map[start].size(); ++i) {
            int v = map[start].get(i);
            dfs(map, dp, v, value);
        }
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int m = cin.nextInt();

        List<Integer>[] map = new ArrayList[n + 1];
        for (int i = 0; i <= n; ++i) {
            map[i] = new ArrayList<>();
        }

        for (int i = 0; i < m; ++i) {
            int u = cin.nextInt();
            int v = cin.nextInt();
            map[v].add(u);
        }

        cin.close();

        int[] dp = new int[n + 1];
        for (int i = n; i >= 1; --i) {
            dfs(map, dp, i, i);
        }
        for (int i = 1; i <= n; ++i) {
            System.out.print(dp[i]);
            System.out.print(" ");
        }
        System.out.println();
    }
}

PyPy

def graph_traversal(aim, start):
    stack = [start]
    
    while stack:
        node = stack.pop()
        if result[node]:
            continue  
        result[node] = aim
        for unit in sub_graph[node]:
            stack.append(unit)

if __name__ == '__main__':
    n, m = map(int, input().split())
    result = [0] * (n + 1)
    sub_graph = [[] for _ in range(n + 1)]

    for _ in range(m):
        u, v = map(int, input().split())
        sub_graph[v].append(u)
    for i in range(n, 0, -1):
        graph_traversal(i, i)

    print(*result[1:])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值