洛谷 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条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...
随机推荐
- CentOS下查看网络状态
查看网络状态:lsof -Pnl +M -i4 显示ipv4服务及监听端情况netstat -anp 所有监听端口及对应的进程netstat -tlnp 功能同上 网络基本命令 (1)network ...
- stack(单调栈) POJ 2082 Terrible Sets
题目传送门 题意:紧贴x轴有一些挨着的矩形,给出每个矩形的长宽,问能组成的最大矩形面积为多少 分析:用堆栈来维护高度递增的矩形,遇到高度小的,弹出顶部矩形直到符合递增,顺便计算矩形面积,且将弹出的宽度 ...
- 修改dns访问android.com
1.几个常用dns服务器 8.8.8.8 美国 加利福尼亚州圣克拉拉县山景市谷歌公司DNS服务器 8.8.4.4 美国 加利福尼亚州圣克拉拉县山景市谷歌公司DNS服务器 8.8.4.3 美国 加利福尼 ...
- 507 Perfect Number 完美数
对于一个 正整数,如果它和除了它自身以外的所有正因子之和相等,我们称它为“完美数”.给定一个 正整数 n, 如果他是完美数,返回 True,否则返回 False示例:输入: 28输出: True解释: ...
- mysql索引命中规则
转于:https://blog.csdn.net/claram/article/details/77574600 首先明确:为什么要用联合索引? 对于查询语句“SELECT E.* FROM E WH ...
- android动画之android:interpolator属性使用
android动画之android:interpolator使用 Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerat ...
- wkWebView 的一些问题
导语 WKWebView 是苹果在 WWDC 2014 上推出的新一代 webView 组件,用以替代 UIKit 中笨重难用.内存泄漏的 UIWebView.WKWebView 拥有60fps滚动刷 ...
- ARM 环境下使用azure powershell 从远程blob中拉去vhd 并创建虚拟机
最近需要从指定公共访问的blob中复制vhd到自己的订阅存储账户,并使用vhd创建AZURE ARM虚拟机(非经典版),而且在portal.azure.cn中无法实现虚拟机映像创建等功能,于是自己使用 ...
- Java编译时根据调用该方法的类或对象所属的类决定
class Base{ int x = 1; static int y = 2; } class Subclass extends Base{ int x = 4; i ...
- 字符串循环右移-c语言
一个长度为len的字符串,对其循环右移n位 [期望]char str[] = "abcdefg";右移3次后,变成"efgabcd" [思路] 思路1. 如果用 ...