我们把“u点能够到达的最大点”转化为反向图中能到达u点的所有点里的最大值,可知缩点后满足无后效性。val[i]的初值设为连通分量i中的最大点。反向存图,tarjan缩点,拓扑序dp即可。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #define maxn 100100
  5. using namespace std;
  6. int n, m;
  7. void read(int &x) {
  8. x = 0;
  9. char ch = getchar();
  10. while (!isdigit(ch))
  11. ch = getchar();
  12. while (isdigit(ch))
  13. x = x * 10 + (ch ^ 48),
  14. ch = getchar();
  15. return;
  16. }
  17. struct E {
  18. int to, nxt;
  19. } edge[maxn], edge2[maxn];
  20. int head[maxn], top, head2[maxn], top2;
  21. inline void insert(int u, int v) {
  22. edge[++top] = (E) {v, head[u]};
  23. head[u] = top;
  24. }
  25. inline void insert2(int u, int v) {
  26. edge2[++top2] = (E) {v, head2[u]};
  27. head2[u] = top2;
  28. }
  29. int low[maxn], dfn[maxn], timer, c[maxn], cnt, sta[maxn], stp;
  30. bool ins[maxn];
  31. int val[maxn];
  32. void tarjan(int u) {
  33. low[u] = dfn[u] = ++ timer;
  34. sta[++stp] = u, ins[u] = true;
  35. for (int i = head[u]; i; i = edge[i].nxt) {
  36. int v = edge[i].to;
  37. if (!dfn[v]) {
  38. tarjan(v);
  39. low[u] = min(low[u], low[v]);
  40. } else if (ins[v])
  41. low[u] = min(low[u], dfn[v]);
  42. }
  43. if (dfn[u] == low[u]) {
  44. ++cnt;
  45. int x;
  46. do {
  47. x = sta[stp--];
  48. ins[x] = false;
  49. c[x] = cnt;
  50. val[cnt] = max(val[cnt], x);
  51. } while (x != u);
  52. }
  53. }
  54. int ind[maxn];
  55. void build() {
  56. for (int u = 1; u <= n; ++u)
  57. for (int i = head[u]; i; i = edge[i].nxt) {
  58. int v = edge[i].to;
  59. if (c[u] != c[v])
  60. insert2(c[u], c[v]), ++ind[c[v]];
  61. }
  62. }
  63. void dp() {
  64. queue<int> que;
  65. for (int i = 1; i <= cnt; ++i)
  66. if (!ind[i]) que.push(i);
  67. while (!que.empty()) {
  68. int u = que.front(); que.pop();
  69. for (int i = head2[u]; i; i = edge2[i].nxt) {
  70. int v = edge2[i].to;
  71. val[v] = max(val[v], val[u]);
  72. --ind[v];
  73. if (!ind[v])
  74. que.push(v);
  75. }
  76. }
  77. return;
  78. }
  79. int main() {
  80. read(n), read(m);
  81. int u, v;
  82. for (int i = 1; i <= m; ++i) {
  83. read(u), read(v);
  84. insert(v, u);
  85. }
  86. for (int i = 1; i <= n; ++i)
  87. if (!dfn[i])
  88. tarjan(i);
  89. build();
  90. dp();
  91. for (int i = 1; i <= n; ++i)
  92. printf("%d ", val[c[i]]);
  93. return 0;
  94. }

至此luogu上真哥留下的缩点习题全部完成。晚上更新对最小树形图(朱刘算法)的理解。

Luogu P43916 图的遍历的更多相关文章

  1. luogu P3916 图的遍历

    P3916 图的遍历 题目描述 给出 N 个点, M 条边的有向图,对于每个点 v ,求 A(v) 表示从点 v 出发,能到达的编号最大的点. 输入输出格式 输入格式: 第1 行,2 个整数 N,MN ...

  2. Luogu P3916 图的遍历 【优雅的dfs】【内有待填坑】By cellur925

    说明 • 对于60% 的数据, n,m在1e3内 • 对于100% 的数据, n,m在1e5内. 本弱弱上来就是一顿暴搜打,dfs n次,每次更新答案,复杂度为O(n*n),果然TLE,60分抱回家. ...

  3. 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次.(连通图与非连通图) 深度优先遍历(DFS): 1.访问指定的起始顶点: 2.若当前访问的顶点的邻接顶点有未被访问的,则 ...

  4. C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构 1)邻接矩阵 用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息. 2)邻接表 3)十字链表 4)邻接多重表 5)边集数组 本文只用代码实现用 ...

  5. Kruskal和prime算法的类实现,图的遍历BFS算法。

    一.图的遍历 #include<iostream> #include<queue> #include<vector> using namespace std; in ...

  6. 图的遍历——DFS(矩形空间)

    首先,这里的图不是指的我们一般所说的图结构,而是大小为M*N的矩形区域(也可以看成是一个矩阵).而关于矩形区域的遍历问题经常出现,如“寻找矩阵中的路径”.“找到矩形区域的某个特殊点”等等之类的题目,在 ...

  7. 图的遍历——DFS和BFS模板(一般的图)

    关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板 1.深度优先搜索(DFS) #include<iostrea ...

  8. 图的遍历算法:DFS、BFS

    在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先 ...

  9. 15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法

    算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: #include<stdio.h> ...

随机推荐

  1. 批量安装Zabbix_Agent

    使用自动化部署工具Ansible批量部署zabbix_agent. 1. 安装Ansible yum –y install ansible 内网情况下,现在ansible及其依赖的rpm包,添加到yu ...

  2. vue-cli3使用jq

    第一步安装 npm install jquery --save 第二部配置vue.config.js, 没有这个文件就创建 主要是框框出来的那些: 忽略我配置的另一个uglifyjs-webpack- ...

  3. SharedPreferences源码分析

    分析达成目标 了解基本实现 SharePreferences是否线程安全 SharePreferences的mode参数是什么 了解apply与commit的区别 导致ANR的原因 Android8. ...

  4. MIPS汇编及模拟器下载

    1. 简述汇编语言发展 在计算机发展初期,人们用0-1序列来表示每一条语言,亦即二进制的机器指令 由于机器指令过于繁琐,程序员们开发出了一种新的语言,这种用符号表示的计算机语言被称为汇编语言 计算机继 ...

  5. Runnable接口和Callable接口的区别

    Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已:Callable接口中的call()方法是有返回值的,是一个泛型,和Future.Fut ...

  6. Go之发送钉钉和邮箱

    smtp发送邮件 群发两个邮箱,一个163,一个QQ package main import ( "fmt" "net/smtp" "strings& ...

  7. find命令的简单使用

    Find命令 格式:find [option] [Path] [筛选条件] [处理动作] Path:默认当前目录 筛选条件:对文件/目录设置筛选条件 处理动作:默认显示所有文件 筛选条件: -name ...

  8. Python爬虫简单实现CSDN博客文章标题列表

    Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...

  9. Round 4

    最近再次经历动荡期 博客只在小白时期记录过 已经沉寂许久 之前的工作在黄区 加班超多  阻隔了一切与外网交流的可能 只能凭记忆补一点最近一年来积累到的知识 不管怎么样 不能放弃自己啊老铁!

  10. php连接神通数据库 ci框架

    神通数据库连接手册 1.扩展安装 目前连接神通数据库有两种方式 ODBC PDO_ACI 具体请看手册,目前使用PDO_ODBC方法PS:请看操作2 目前只有64位有pdo_aci.so文件,需要在神 ...