洛谷 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条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...
随机推荐
- Jquery | 基础 | 慕课网 | 基本筛选选择器
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content ...
- Jmeter之一个请求获取上一个请求的参数
刚开始有这个需求,网上都是一些使用正则表达式的例子,苦于自己看不好正式的表达式,且响应结果稍微变一下,自己就不会写了,于是谷歌上各种搜,也阅读官网上文档,后来发现一个好的插件 Json path Ex ...
- LightOj 1076 - Get the Containers (折半枚举好题)
题目链接: http://www.lightoj.com/volume_showproblem.php?problem=1076 题目描述: 给出n个数,要求分成m段,问这m段中最大的总和,最小是多少 ...
- Stars in Your Window POJ - 2482
错误记录: 题目说输入在int范围内,但是运算过程中可能超int:后来开了很多longlong就过了 #include<cstdio> #include<algorithm> ...
- Beautiful People SGU - 199 ZOJ - 2319
最长上升子序列O(n log n):http://www.cnblogs.com/hehe54321/p/cf-340d.html 题目:https://cn.vjudge.net/problem/Z ...
- Maven聚合模式
项目的打包类型:pom.jar.war 项目中一般使用maven进行模块管理,每个模块下对应都有一个pom文件,pom文件中维护了各模块之间的依赖和继承关系.项目模块化可以将通用的部分抽离出来,方便重 ...
- vmware让虚拟机内外网络可互访
以下方法可使主机可以ping通虚拟机,虚拟机也可以ping通主机 首先对虚拟机设置 然后设置虚拟机,假设主机的ip是10.0.0.9,那虚拟机的ip应如下设置: 其中ip地址任意设置一个,但要求跟主机 ...
- Android基础夯实--重温动画(二)之Frame Animation
心灵鸡汤:天下事有难易乎,为之,则难者亦易矣:不为,则易者亦难矣. 摘要 当你已经掌握了Tween Animation之后,再来看Frame Animation,你就会顿悟,喔,原来Frame Ani ...
- kde framework概述(KDE Framework译文)
KDE Frameworks 基于QT框架,提供简单实用的类(例如那些KCoreAddons里的类)去为桌面应用的日常需要整合出解决方案(例如KNewStuff用于在应用中获取可下载的附加内容,或者那 ...
- Java Web 开发中路径相关问题小结
Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 图1 Eclipse中目录结构如图2所示: 图2 那么针对这个站点的几个基本概 ...