原题入口

PS:这个题数据是由Hany01大大出出来的 %%%

这个题显然是一道强联通+DAGdp的题 (题目背景有= =)

缩点的原因就是:不缩会一直在一个地方绕圈圈 而且不能进行后面的DAPdp 而且给你的所有点权全是正的

我在这用的是Tarjan(因为他发明算法太多了233)

这个dp方程比较容易找 令dp[u] 表示 缩点后 第u个强联通分量为起点的路径上点和的最大值

所以有 dp[u] = max{dp[v]} + val[u]  (这里v是指u出发可以到达的点)

由于是DAGdp 所以我们一开始要从入度为0的点出发 一直向下走 回溯的时候更改这个节点的dp值

下附程序(Tarjan讲解见程序):

#include <bits/stdc++.h>
#define For(i, l, r) for(int i = (l); i <= (int)(r); ++i)
#define Fordown(i, r, l) for(int i = (r); i >= (int)(l); --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std; inline int read() {
int x = , fh = ; char ch;
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -;
for (; isdigit(ch); ch = getchar()) x = (x<<) + (x<<) + (ch^'');
return x * fh;
} #include <stack>
const int N = 1e4+1e2, M = 1e5*+1e2; //点的范围和边的范围 开大点防止数据bug
struct edge {
int to[M], Next[M], Head[N], e;
void init() {Set(Head, ); e = ;}
}; //用链式前向星存边,访问更加迅速
edge G1, G2; //结构体便于多图 void add_edge (int u, int v, edge &G) { //引用G为了更新G
G.to[++G.e] = v;
G.Next[G.e] = G.Head[u];
G.Head[u] = G.e;
} //加入一条有向边 #define Travel(i, u, G) for(int i = G.Head[u]; i; i = G.Next[i])
//链式前向星的遍历方式 i表示在G图中,所有从u出发的边 (宏定义偷懒233)
int pre[N], lowlink[N], sccno[N], dfs_clock = , scc_cnt = ;
stack<int> S;
//Tarjan所需要的一些变量,时间戳dfs_clock,最早进入时间pre,能访问最远祖先lowlink
//强联通分量总数scc_cnt,每个点所属强联通分量编号sccno
int val[N], val1[N];
//val表示原图中的权值,val1表示缩点后每个强联通分量的权值
void Tarjan (int u) { //Tarjan主体(访问u)
pre[u] = lowlink[u] = ++dfs_clock; //第一次进入 把时间和最远到达祖先设为u
S.push(u); //把u放入栈中
Travel (i, u, G1) { //遍历原图从u开始的节点
int v = G1.to[i]; //取出到达的节点
if (!pre[v]) { //没有访问过
Tarjan (v); //递归向下继续搜
lowlink[u] = min(lowlink[u], lowlink[v]); //更新能到达最远祖先的值
} else if (!sccno[v]) //不是别的强联通分量中的点 且 已经访问过了(也就是存在了一条返祖边)
lowlink[u] = min(lowlink[u], pre[v]); //更新最远祖先(因为v在u之前被访问)证明有环
}
if (lowlink[u] == pre[u]) { //能到达的最远祖先就是自己
++scc_cnt; //将总数增加
for(;;) { //不断递归
int now = S.top(); S.pop(); //取出当前栈顶的数
sccno[now] = scc_cnt; //标记点的编号
val1[scc_cnt] += val[now]; //统计强联通分量的权值
if (now == u) break; //到了自己就停下来 不可能继续向上走了
}
}
} int in_deg[N]; //记录入度
int max_ans = ; //答案
int dp[N]; //dp数组
bool vis[N]; //标记是否到达
void dfs(int u) {
if (vis[u]) return;
vis[u] = true; //似乎不要也行 但好像更慢
dp[u] = val1[u]; //初始化标记为强联通得权值
Travel (i, u, G2) { //从缩点后的图开始遍历
int v = G2.to[i]; //取出到达点
dfs(v); //向下遍历
dp[u] = max(dp[u], dp[v] + val1[u]); //回溯时更新dp值
}
max_ans = max(max_ans, dp[u]); //更新答案
} int main() {
int n = read(), m = read();
G1.init(); G2.init();
For (i, , n)
val[i] = read();
while (m--) {
int u = read(), v = read();
add_edge (u, v, G1); //把边加入G1中
}
For (i, , n)
if (!pre[i]) Tarjan (i); //搜索强联通 For (i, , n)
Travel (j, i, G1) { //遍历所有的边
int v = G1.to[j];
if (sccno[i] == sccno[v]) continue; //如果在同一个强联通分量中就向下走
add_edge (sccno[i], sccno[v], G2); //把新边加入G2中
++in_deg[sccno[v]]; //增加v入度
} For (i, , scc_cnt)
if (!in_deg[i]) dfs(i); //搜索入度为0的点
printf ("%d\n", max_ans);
}

luogu【P3387】【模板】缩点的更多相关文章

  1. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

  2. [luogu P3384] [模板]树链剖分

    [luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...

  3. Luogu P2742 模板-二维凸包

    Luogu P2742 模板-二维凸包 之前写的实在是太蠢了.于是重新写了一个. 用 \(Graham\) 算法求凸包. 注意两个向量 \(a\times b>0\) 的意义是 \(b\) 在 ...

  4. luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

    luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目 #include<iostream> #include<cstdlib> #include< ...

  5. 解题报告+板子:luogu P3387 【模板】缩点

    题目链接:P3387 [模板]缩点 缩点板子,所谓\(dp\)就是拓扑排序(毕竟可以重走边),像\(SPFA\)一样松弛就好,就是重边极其烦人,还加了排序(绝对自己想的,然鹅拓扑的思路不是). 下面上 ...

  6. luogu P3387 【模板】缩点

    题目 好久没法博客了 这次就水个板子题目吧 tarjan缩点之后重新建图 而且边权应该都是正的(要不我怎么能这么轻松水过去) 在新图上记忆化一下就好了 f[i] 表示 开头选i这个点 的 路径最大值 ...

  7. LUOGU P3387 【模板】缩点 (缩点+DAG dp)

    解题思路 缩点后按拓扑排序跑一个dp. #include<iostream> #include<cstdio> #include<cstring> #include ...

  8. luogu P3387 【模板】缩点_拓扑排序

    还是很好些的. Code: #include <stack> #include <cstdio> #include <algorithm> #include < ...

  9. Tarjan+topsort(DP)【P3387】 [模板]缩点

    Description 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次 ...

  10. [模板](luogu P3387)縮點

    前言:對於這週的咕咕咕表示好像沒什麼好表示的,完全沒有靈感a......寫東西真的好難啊......於是又玩了半天鬼泣4???還挺好玩的 來源:題解 题目背景 缩点+DP 题目描述 给定一个n个点m条 ...

随机推荐

  1. MySQL数据类型概念

    关系型数据库的特点 1,数据以表格的形式出现 2,每行为各种记录的名称 3,每列为数据名称所对应的数据域 4许多的行和列组成一张table 5若干的表单组成databases 术语 数据库:关联表的集 ...

  2. maven的下载安装,配置本地仓库

    maven的下载安装 下载地址:http://maven.apache.org/download.cgi 下载完成后解压到某一个目录 配置环境变量 第一个环境变量 MAVEN_HOME A:\mave ...

  3. GO开发:接口

    接口 接口定义 Interface类型可以定义一组方法,但是这些不需要实现.并且interface不能包含任何变量. type example interface{ Method1(参数列表) 返回值 ...

  4. easyui datagrid 右边框被隐藏

    问题前: 如下图: 解决思路: 待文档加载完成后再执行dategrid函数 $(function () { $("#tt").datagrid({ //....... }); }) ...

  5. Docker第一弹:下载运行hello-world程序

    1.需要安装好docker程序 没有安装的请看在centos 6.8下安装docker 2.从docker镜像仓库中拉去hello-world镜像 docker pull hello-world 3. ...

  6. hibhibernate中hql中的语句where语句查询List出现空

    1.java.sql.Date 与 java.util.Date java.sql.Date是从java.util.Date中继承而来 假设 dates1(java.sql.Date)要赋值给date ...

  7. 隐藏文件的查看(Win/Linux/macOS)

    Windows(10): 点查看->点选项,弹出文件夹选项,点查看,高级设置里找到隐藏文件和文件夹这个选项,按需求选显示或者隐藏即可. Linux: Linux下,类似于.ssh开头的文件或者文 ...

  8. Yii的URL助手

    Url 帮助类 获得通用 URL 记住 URLs 检查相对 URLs Url 帮助类提供一系列的静态方法来帮助管理 URL. 获得通用 URL 有两种获取通用 URLS 的方法 :当前请求的 home ...

  9. 浏览器输入URL到响应页面的全过程

    B/S网络架构从前端到后端都得到了简化,都基于统一的应用层协议HTTP来交互数据,HTTP协议采用无状态的短链接的通信方式,通常情况下,一次请求就完成了一次数据交互,通常也对应一个业务逻辑,然后这次通 ...

  10. Python实现二分查找

    老生常谈的算法了. #!/usr/bin/python # -*- coding:utf-8 -*- # Filename: demo.py # 用python实现二分查找 def binarySea ...