洛谷 P3387 【模板】缩点 DAGdp学习记
我们以洛谷P3387 【模板】缩点 来学习DAGdp
1.这道题的流程
//伪代码
for i->n if(i未被遍历) tarjan(i)
缩点()
DAGdp()
完成
首先tarjan这部分应该没问题,如果想看详细的可以看我的tarjan学习记
接下来tarjan完毕,每个点属于的强连通分量也得到了,因此缩点可以进行了
这里这部分比较麻烦,下面上的代码讲的比较清楚,注释也给了。
所以现在讲讲DAGdp
我刚开始看到DAPdp……什么鬼啊?(UPD:DAG为有向无环图),然后百度,啥都没有,于是自己用类似用类似拓扑排序的方法做,发现DAGdp就是在拓扑上面弄得,那么,这就好办了
void dagdp()
{
int i,j;
queue <int> q;
for(i=;i<=cnt;i++)
{
if(!ind[i]) //找到入度为0的点,这个点一定不会被刷新,因此满足dp无后效性
{
q.push(i);
f[i]=money[i];
}
}
while(!q.empty())
{
int t=q.front();
int i,j,k;
q.pop();
for(i=head[t];i;i=e[i].next)
{
j=e[i].to;
ind[j]--; //这个点的入度减一
k=money[j];
f[j]=max(f[t]+k,f[j]);
if(!ind[j]) //如果这个点入度为0,那么这个点一定被处理完了
q.push(j); //那么又可以从这个点开始做
}
}
}
因此,这道题的程序就长这个样子
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack> using namespace std; int size,n,m,dt,cnt;
int head[],cost[],vis[],bd[],ins[],dfn[],low[],money[];
stack <int> s;
int ind[],chd[],f[],ans=-,bl;
struct edge{
int next,to,dis;
}e[],looker[]; //looker是存的边的备份 void addedge(int next,int to,int dis)
{
e[++size].dis=dis;
e[size].to=to;
e[size].next=head[next];
head[next]=size;
} int pd(int a,int b) //判断边是否重复
{
for(int i=head[a];i;i=e[i].next)
{
int j=e[i].to;
if(j==b) return ;
}
return ;
} void tarjan(int t) //tarjan操作
{
dfn[t]=low[t]=++bl;
s.push(t);
ins[t]=;
int i,j;
for(i=head[t];i;i=e[i].next)
{
j=e[i].to;
if(!dfn[j])
{
tarjan(j);
low[t]=min(low[t],low[j]);
}
else if(ins[j]) low[t]=min(dfn[j],low[t]);
}
j=;
if(dfn[t]==low[t])
{
cnt++;
while(t!=j)
{
j=s.top();
s.pop();
ins[j]=;
bd[j]=cnt;
}
}
} void dagdp()
{
int i,j;
queue <int> q;
for(i=;i<=cnt;i++)
{
if(!ind[i]) //找到入度为0的点,这个点一定不会被刷新,因此满足dp无后效性
{
q.push(i);
f[i]=money[i];
}
}
while(!q.empty())
{
int t=q.front();
int i,j,k;
q.pop();
for(i=head[t];i;i=e[i].next)
{
j=e[i].to;
ind[j]--; //这个点的入度减一
k=money[j];
f[j]=max(f[t]+k,f[j]);
if(!ind[j]) //如果这个点入度为0,那么这个点一定被处理完了
q.push(j); //那么又可以从这个点开始做
}
}
} int main()
{
int i,j;
scanf("%d %d",&n,&m);
for(i=;i<=n;i++)
scanf("%d",&cost[i]);
for(i=;i<=m;i++)
{
int t1,t2;
scanf("%d %d",&t1,&t2);
addedge(t1,t2,);
looker[i].next=t1;
looker[i].to=t2;
}
for(i=;i<=n;i++) if(!dfn[i])tarjan(i);
memset(head,,sizeof(head));
size=;
for(i=;i<=n;i++)
{
money[bd[i]]+=cost[i];
}
for(i=;i<=m;i++)
{
if(bd[looker[i].next]==bd[looker[i].to]) continue; //我 到 我自己 ?
if(!pd(bd[looker[i].next],bd[looker[i].to]))
{
addedge(bd[looker[i].next],bd[looker[i].to],);
ind[bd[looker[i].to]]++; //统计入度与出度
chd[bd[looker[i].next]]++;
}
}
dagdp();
for(i=;i<=cnt;i++) ans=max(ans,f[i]); //比较每个点与当前最大值
printf("%d",ans);
return ;
}
洛谷 P3387 【模板】缩点 DAGdp学习记的更多相关文章
- 洛谷P3387 【模板】缩点 题解
		背景 今天\(loj\)挂了,于是就有了闲情雅致来刷\(luogu\) 题面 洛谷P3387 [模板]缩点传送门 题意 给定一个\(n\)个点\(m\)条边有向图,每个点有一个权值,求一条路径,使路径 ... 
- tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
		缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ... 
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
		To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ... 
- 洛谷——P3387 【模板】缩点
		P3387 [模板]缩点 题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点, ... 
- 洛谷P3387 【模板】缩点
		题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ... 
- 洛谷 P3387 【模板】缩点
		题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ... 
- 洛谷P3375 [模板]KMP字符串匹配
		To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ... 
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
		为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ... 
- 洛谷 P2656 (缩点 + DAG图上DP)
		### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ... 
随机推荐
- ADB over Wi-Fi
			ADB over Wi-Fi 1.root $adb root 2.设置tcp端口并重启tcpip服务 $adb shell setprop persist.adb.tcp.port &&am ... 
- PowerShell~文件操作和对象遍历
			ps提供了丰富的文件操作,如建立,删除,改名,移动,复制,文件夹建立,显示文件列表,同时对数组对象的遍历也很方便,如果在使用PS脚本时,希望现时传入参数,可以把参数声明为param,当然需要把它写在文 ... 
- Spring------自动化装配Bean(一)
			一.创建 CompactDisc接口和SgetPeppers实现类 CompactDisc接口方法为播放.SgtPeppers实现CompactDisc接口. package soundsystem; ... 
- Javaweb学习笔记10—文件上传与下载
			今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容. ... 
- JSP和Servlet性能优化经验谈
			你的J2EE应用是不是运行的很慢?它们能不能承受住不断上升的访问量?本文讲述了开发高性能.高弹性的JSP页面和Servlet的性能优化技术.其意思是建立尽可能快的并能适应数量增长的用户及其请求.在本文 ... 
- 跟随鼠标指针跑的div拖拽效果
			<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ... 
- 如何安装Virtual Box的VBox Guest Additions扩展程序
			Virtual Box的默认安装是不包含Guest Addition这个扩展的,在实际使用过程中带来种种不便,比如只能通过小窗口访问虚拟机的操作系统,通过默认的右Ctrl切换鼠标,不能和宿主操作系统共 ... 
- Web开发者不容错过的10个HTML5工具
			HTML5已经成为当今世界的一个必然组成部分.由于World Wide Web万维网是使用超文本标记语言来架构和呈现的,于是HTML5成为了最流行的编程语言之一.随着网络的不断扩张,Web开发人员非常 ... 
- 如何理解Python中的if __name__ == '__main__'
			1. 摘要 通俗的理解__name__ == '__main__':假如你叫小明.py,在朋友眼中,你是小明(__name__ == '小明'):在你自己眼中,你是你自己(__name__ == '_ ... 
- vscode 快捷键 ctrl+shift+F 冲突了 解决办法
			vscode 快捷键 ctrl+shift+F 冲突了 解决办法 1.修复 搜狗输入法 ctrl+shift+F 中文 繁体简体的快捷键冲突 2.修复 微软输入法 ctrl+shift+F 冲突 ( ... 
