洛谷P4742 [Wind Festival]Running In The Sky [Tarjan缩点,DAGDP]
Running In The Sky
格式难调,题面就不放了。
分析:
一句话题意:给定一张带点权的有向图,求最长点权路径及该路径上的最大点权。
很明显的$DAGDP$,因此需要缩点,将该图重建为一张$DAG$,在每个强联通分量中记录两个变量$sum,mx$表示该强联通分量中的点权和及最大点权。然后就是$DP$了,因为不仅要求最长点权路径,还要求路径上的最大点权,所以我们可以记录状态$f[x][0]$和$f[x][1]$分别表示以$x$为终点的路径中点权和最大的路径以及该路径上的最大点权。共有两个方程:
$\begin{cases}f[y][0]=f[x][0],f[y][1]=f[x][1] & (f[x][0]>f[y][0])\\f[y][1]=max(f[y][1],f[x][1]) & (f[x][0]==f[y][0]) \end{cases}$
这样子这题就很好解决了。
Code:
//It is made by HolseLee on 26th Oct 2018
//Luogu.org P4742
#include<bits/stdc++.h>
using namespace std; const int N=2e5+, M=5e5+;
int n,m,val[N],ans0,ans1,h[N],head[N],cnte,dg[N],f[N][];
int scc[N],mx[N],sum[N],idx,dfn[N],low[N],tot;
bool ins[N];
struct Edge { int to,nxt; }edge[M],e[M];
queue<int>q; stack<int>t; inline int read()
{
char ch=getchar(); int x=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=true; ch=getchar(); }
while( ch>='' && ch<='' ) {
x=x*+ch-''; ch=getchar(); }
return flag ? -x : x;
} inline void add_edge(int x,int y)
{
edge[++cnte].to=y;
edge[cnte].nxt=h[x];
h[x]=cnte;
} inline void add(int x,int y)
{
e[++cnte].to=y, e[cnte].nxt=head[x];
head[x]=cnte, dg[y]++;
} void tarjan(int x)
{
dfn[x]=low[x]=++idx; ins[x]=; t.push(x);
int y;
for(int i=h[x]; i; i=edge[i].nxt) {
y=edge[i].to;
if( !dfn[y] ) {
tarjan(y);
low[x]=min(low[x],low[y]);
} else if( ins[y] ) {
low[x]=min(low[x],dfn[y]);
}
}
if( dfn[x]==low[x] ) {
++tot;
do {
y=t.top(); t.pop(); ins[y]=false; scc[y]=tot;
sum[tot]+=val[y], mx[tot]=max(mx[tot],val[y]);
} while( y!=x );
}
} void rebuild()
{
cnte=;
for(int x=; x<=n; ++x)
for(int i=h[x],y; i; i=edge[i].nxt) {
y=edge[i].to;
if( scc[x]!=scc[y] ) add(scc[x],scc[y]);
}
} int main()
{
n=read(), m=read();
for(int i=; i<=n; ++i) val[i]=read();
for(int i=; i<=m; ++i) add_edge(read(), read());
for(int i=; i<=n; ++i) if( !dfn[i] ) tarjan(i);
rebuild();
for(int i=; i<=tot; ++i) if( !dg[i] ) q.push(i);
while( !q.empty() ) {
int x=q.front(); q.pop();
f[x][]+=sum[x]; f[x][]=max(f[x][],mx[x]);
for(int i=head[x],y; i; i=e[i].nxt) {
y=e[i].to;
if( !(--dg[y]) ) q.push(y);
if( f[x][]>f[y][] ) {
f[y][]=f[x][], f[y][]=f[x][];
} else if( f[y][]==f[x][] ) {
f[y][]=max(f[y][],f[x][]);
}
}
}
for(int i=; i<=tot; ++i)
if( f[i][]>ans0 ) {
ans0=f[i][], ans1=f[i][];
} else if( f[i][]==ans0 ) {
ans1=max(ans1,f[i][]);
}
printf("%d %d\n",ans0,ans1);
return ;
}
洛谷P4742 [Wind Festival]Running In The Sky [Tarjan缩点,DAGDP]的更多相关文章
- T25990 [Wind Festival]Running In The Sky
T25990 [Wind Festival]Running In The Sky 题目背景 [Night - 20:02[Night−20:02 P.M.]P.M.] 夜空真美啊--但是--快要结束了 ...
- P4742 【[Wind Festival]Running In The Sky】
相信来做这道题的人肯定都学过\(Tarjan\)缩点吧,如果没有建议先去做P3387 [模板]缩点,如果你忘了,建议也去看看 满足上面要求后,你会惊奇发现,这两道题基本一样,唯一的差别就是这道题需要记 ...
- 「洛谷3469」「POI2008」BLO-Blockade【Tarjan求割点】
题目链接 [洛谷传送门] 题解 很显然,当这个点不是割点的时候,答案是\(2*(n-1)\) 如果这个点是割点,那么答案就是两两被分开的联通分量之间求组合数. 代码 #include <bits ...
- 2019/5/13 洛谷P4742 【tarjan缩点 + 拓扑dp】
题目链接:https://www.luogu.org/problemnew/show/P4742 题目大意:给一张有向图, 每个点都有点权,第一次经过该点时,该点的点权有贡献,求这张图上一条路径(终点 ...
- 洛谷P1353 USACO 跑步 Running
题目 一道入门的dp,首先要先看懂题目要求. 容易得出状态\(dp[i][j]\)定义为i时间疲劳度为j所得到的最大距离 有两个坑点,首先疲劳到0仍然可以继续疲劳. 有第一个方程: \(dp[i][0 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur (SCC缩点,SPFA最长路,枚举反边)
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 In an effort to better manage the grazing patterns of hi ...
- 洛谷P2341 [HAOI2006]受欢迎的牛 (Tarjan,SCC缩点)
P2341 [HAOI2006]受欢迎的牛|[模板]强连通分量 https://www.luogu.org/problem/P2341 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就 ...
- 洛谷P2863 [USACO06JAN]The Cow Prom S (tarjan)
题目简述:一个有向图,求出这个图点数>1的强连通分量的个数. 那么就是tarjan求强联通分量的模板了. 记得要用一个数组标记节点是否在栈中. 1 #include<bits/stdc++ ...
- 洛谷 1938 [USACO09NOV]找工就业Job Hunt
洛谷 1938 [USACO09NOV]找工就业Job Hunt 题目描述 Bessie is running out of money and is searching for jobs. Far ...
随机推荐
- 借读:分布式锁和双写Redis
本帖最后由 howtodown 于 2016-10-3 16:01 编辑问题导读1.为什么会产生分布式锁?2.使用分布式锁的方法有哪些?3.本文创造的分布式锁的双写Redis框架都包含哪些内容? ...
- Qt ------ QTableView QTableWidget
QTableView model提供数据 view提供视图 view用来显示model的数据 必须将model绑定到某个view中才能显示 QStandardItemModel* mod ...
- spring boot 事务配置
事务的作用这里不细说,相信很多人也在工作中使用过. 那么在spring-boot是如何配置事务的,事实上非常简便. 直接贴代码吧. 首先配置数据源 myqlDataSource,这个就不说了.之前的 ...
- shift 用法
shift shift命令用于对参数的移动 (左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理(常见于Linux中各种程序的启动脚本). 示例 1 示例 依次读取输入的 ...
- Linux - 磁盘操作
Linux 磁盘常见操作 : df -Ph # 查看硬盘容量 df -T # 查看磁盘分区格式 df -i # 查看inode节点 如果inode用满后无法创建文件 du -h 目录 # 检测目录下所 ...
- VIM 配置随手记
刚开始使用VIM, 主要想用它来写python. 目标是颜色比较舒适, 并且能够自动换行自动补全. .vimrc 设置 这是类似 .bashrc 的配置文件, vim 的各种配置都可以在里面实现. 一 ...
- Linux Core Dump【转】
转自:http://www.cnblogs.com/hazir/p/linxu_core_dump.html 当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中 ...
- python基础-装饰器,生成器和迭代器
学习内容 1.装饰器 2.生成器 3.迭代器 4.软件目录结构规范 一:装饰器(decorator) 1.装饰器定义:本质就是函数,用来装饰其他函数,即为其他函数添加附加功能. 2.装饰器原则:1)不 ...
- postman发送json请求,使用案例
介绍: postman是一个很好的http模拟器,,可以发送get.post.put等各种请求,是测试服务接口相当好的工具. postman发送json请求,使用案例 发送json的具体步骤: 1. ...
- 细说MySQL备份的基本原理(系列一 ) 备份与锁
数据库作为一个系统中唯一或者主要的持久化组件,对服务的可用性和数据的可靠性要求极高. 作为能够有效应对因为系统软硬件故障.人工误操作导致数据丢失的预防手段,备份是目前最为常见的数据库运维操作. 考虑到 ...