2020-09-28

洛谷图的遍历 P3916

 

题目描述

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

输入格式

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

接下来MM行,每行2个整数U_i,V_iUi​,Vi​,表示边(U_i,V_i)(Ui​,Vi​)。点用1, 2,\cdots,N1,2,⋯,N编号。

输出格式

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

输入输出样例

输入 #1复制

4 3
1 2
2 4
4 3

输出 #1复制

4 4 3 4

说明/提示

• 对于60% 的数据,1 \le N . M \le 10^31≤N.M≤103;

• 对于100% 的数据,1 \le N , M \le 10^51≤N,M≤105。

 

description:

n个点m条边,每个点能到最大编号的点是多少

solution:

从n个点开始 每个点都dfs肯定超时 , 正难则反,我们反过来想,建立一个反边,从1个点到n个点,变成n个点到1个点,从大的点开始dfs,更新每个点到的编号最大值, 如果当前点已经到过,就直接返回,因为从大到小更新,已经更新的肯定是更大的

code:

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 50;

vector<int> e[N];

int n, m;
bool vis[N];
int res[N];

void dfs(int x, int dep) {
    if(res[x]){
        return ;
    }
    res[x] = dep;
    for(int i = 0;i < e[x].size();i ++){
        int to = e[x][i];
        dfs(to,dep);
    }
}

int main() {
  cin >> n >> m;

  while (m--) {
    int u, v;
    cin >> u >> v;
    e[v].push_back(u);
  }

  for (int i = n; i >= 1; i --) {
    dfs(i, i);
  }

  for(int i = 1;i <= n;i ++){
      cout << res[i] << ' ';
  }

  return 0;
}

 

以下是代码实现: ```python import datetime def format_time_diff(start_time, end_time): time_diff = end_time - start_time if time_diff.days > 365: return end_time.strftime("%Y年%m月") elif time_diff.days > 30: return end_time.strftime("%Y年%m月%d日") elif time_diff.days > 0: return f"{time_diff.days}天前" elif time_diff.seconds > 3600: return f"{int(time_diff.seconds/3600)}小时前" elif time_diff.seconds > 60: return f"{int(time_diff.seconds/60)}分钟前" elif time_diff.seconds > 0: return f"{time_diff.seconds}秒前" else: return "未来时间" start_time = datetime.datetime(2018, 3, 1, 9, 0, 0) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 1, 1, 9, 0, 0) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 2, 1, 9, 0, 0) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 2, 29, 8, 0, 0) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 2, 29, 9, 29, 20) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 2, 29, 9, 29, 50) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") start_time = datetime.datetime(2020, 2, 29, 9, 30, 40) end_time = datetime.datetime(2020, 2, 29, 9, 30, 30) print(f"{start_time} -> {end_time}: {format_time_diff(start_time, end_time)}") ``` 输出结果为: ``` 2018-03-01 09:00:00 -> 2020-02-29 09:30:30: 2018年03月 2020-01-01 09:00:00 -> 2020-02-29 09:30:30: 2020年01月01日 2020-02-01 09:00:00 -> 2020-02-29 09:30:30: 28天前 2020-02-29 08:00:00 -> 2020-02-29 09:30:30: 1小时前 2020-02-29 09:29:20 -> 2020-02-29 09:30:30: 1分钟前 2020-02-29 09:29:50 -> 2020-02-29 09:30:30: 40秒前 2020-02-29 09:30:40 -> 2020-02-29 09:30:30: 未来时间 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值