洛谷P3387 缩点模板
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
因为可以重复经过点,所以一个点所在的强联通分量必定可以到达。所以直接缩点即可。
缩点之后,我们要让权值最大化,必须从入度为0的点开始搜。因为这是DAG,入度不为零的点的最后祖先必定是入度为零的点。由于这道题没有负数权值,从入度为零的结点开始走肯定是一个最好的选择。然后DAG上跑动归即可。
#include <cstdio>
#include <cstring>
using namespace std; const int maxn=1e4+, maxm=1e5+; class Graph{
public:
//为什么用嵌套类,因为声明很烦。。并不是访问问题的原因。
//如果类的成员不是static的话,内部类是不知道获取哪个外部类对象的。。
//所以无论是把类放在里面还是外面,访问都有问题。
//另外,把private放在下面,应该是因为嵌套类类必须完全声明才能使用吧。。
//我也不大清楚。。先这么用着,以后再去翻c++ primer。
class Edge{
private:
Graph *belong;
public:
int v, to, next; //感觉这里还是不优雅。。
Edge(){}
Edge(Graph& g, int x, int y, int z){
belong=&g;
to=x, v=y, next=z;
}
Edge operator ++(){ //不能打引用!
*this=belong->edge[next]; //因为有自增运算,这个edge不能等同于图中的!
return *this;
}
int operator *(){
return to;
}
};
Graph(){}
void addedge(int x, int y, int v){
++cntedge;
edge[cntedge]=Edge(*this, y, v, fir[x]);
fir[x]=cntedge;
return;
}
Edge get_link(int x){ //这里改成begin较好
return edge[fir[x]];
}
private:
int cntedge, fir[maxn];
Edge edge[maxm];
}; int n, m, cnttime, cntscc;
int v[maxn], visit[maxn], time[maxn];
int scc[maxn], vofscc[maxn], in[maxn], ans[maxn];
Graph g, g_t, g_scc; void dfs(int now, int flag){
visit[now]=;
Graph::Edge e=g.get_link(now);
if (flag==) e=g_t.get_link(now);
int to=*e;
while (to){
if (!visit[to]) dfs(to, flag);
to=*(++e);
}
if (flag==){
++cnttime;
time[cnttime]=now;
}
if (flag==) {
scc[now]=cntscc;
vofscc[cntscc]+=v[now];
}
return;
} void dfs2(int x){
Graph::Edge e=g.get_link(x);
int to=*e;
visit[x]=;
while (to){
if (scc[to]!=scc[x]){
g_scc.addedge(scc[x], scc[to], v[scc[to]]);
++in[scc[to]];
}
if (!visit[to])
dfs2(to);
to=*(++e);
}
return;
} void dfs3(int x){
Graph::Edge e=g_scc.get_link(x);
int to=*e;
visit[x]=;
ans[x]=vofscc[x];
while (to){
if (!visit[to]) dfs3(to);
if (ans[to]+vofscc[x]>ans[x])
ans[x]=ans[to]+vofscc[x];
to=*(++e);
}
return;
} int main(){
scanf("%d%d", &n, &m);
for (int i=; i<=n; ++i)
scanf("%d", &v[i]);
int x, y;
for (int i=; i<=m; ++i){
scanf("%d%d", &x, &y);
g.addedge(x, y, );
g_t.addedge(y, x, );
} //建图
for (int i=; i<=n; ++i)
if (!visit[i]) dfs(i, ); //时间戳
memset(visit, , sizeof(visit));
for (int i=n; i>; --i){
if (!visit[time[i]]){
++cntscc;
dfs(time[i], );
}
} //求强联通分量
memset(visit, , sizeof(visit));
for (int i=; i<=n; ++i){
if (!visit[i]) dfs2(i);
} //缩点
for (int i=; i<=cntscc; ++i)
if (!in[i]) g_scc.addedge(, i, vofscc[i]); //超级源汇
memset(visit, , sizeof(visit));
dfs3(); //树形dp
printf("%d\n", ans[]);
return ;
}
洛谷P3387 缩点模板的更多相关文章
- 洛谷P3387缩点
传送门 有向图.. 代码中有两种方法,拓扑排序和记忆化搜索 #include <iostream> #include <cstdio> #include <cstring ...
- 洛谷P3387 【模板】缩点 题解
背景 今天\(loj\)挂了,于是就有了闲情雅致来刷\(luogu\) 题面 洛谷P3387 [模板]缩点传送门 题意 给定一个\(n\)个点\(m\)条边有向图,每个点有一个权值,求一条路径,使路径 ...
- 洛谷 P3387 【模板】缩点 DAGdp学习记
我们以洛谷P3387 [模板]缩点 来学习DAGdp 1.这道题的流程 //伪代码 for i->n if(i未被遍历) tarjan(i) 缩点() DAGdp() 完成 首先tarjan这部 ...
- tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...
- 【洛谷P3369】【模板】普通平衡树题解
[洛谷P3369][模板]普通平衡树题解 题目链接 题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3 ...
- 【洛谷4721】【模板】分治FFT(CDQ分治_NTT)
题目: 洛谷 4721 分析: 我觉得这个 "分治 FFT " 不能算一种特殊的 FFT ,只是 CDQ 分治里套了个用 FFT (或 NTT)计算的过程,二者是并列关系而不是偏正 ...
- 【洛谷3865】 【模板】ST表(猫树)
传送门 洛谷 Solution 实测跑的比ST表快!!! 这个东西也是\(O(1)\)的,不会可以看我上一篇Blog 代码实现 代码戳这里
- 洛谷——P3387 【模板】缩点
P3387 [模板]缩点 题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点, ...
- 【模板】缩点(Tarjan算法)/洛谷P3387
题目链接 https://www.luogu.com.cn/problem/P3387 题目大意 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之 ...
随机推荐
- 数据库+maven
1.mysql <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-ja ...
- Mysql备份和还原(命令)
1.备份方法一 ①.进入数据库 mysql -uroot -p pwd; ②.查看数据库 show databases; ③.备份数据库 mysqldump -hlocalhost -uroot(用户 ...
- 机器学习(二十四)— 偏差Bias 与方差Variance
1.首先 Error = Bias + Variance Error反映的是整个模型的准确度, Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度, Variance反映的是模 ...
- vuex使用mapActions报错解决办法
先贴上报错: vuex2增加了mapGetters和mapActions的方法,借助stage2的Object Rest Operator 所在通过 methods:{ ...mapActions([ ...
- C++中getline的用法
在看紫皮书的时候看到getline,然后查了查具体用法,记录下来. #include"iostream" #include"string" using name ...
- spark减少提交jar包处理
spark一个应用,算上依赖一百多兆.每一次都如此,坑. 首先是<packing>jar</packing>这只为打包为jar,在plugin中增加一个assembly插件,这 ...
- BZOJ1720:[Usaco2006 Jan]Corral the Cows 奶牛围栏
我对二分的理解:https://www.cnblogs.com/AKMer/p/9737477.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...
- C#创建DataTable的语法
namespace EazyCMS.Web.admin { public partial class ceshi1 : System.Web.UI.Page { protected void Page ...
- poj 1519 Digital Roots (计算根数字)
一.Description The digital root of a positive integer is found by summing the digits of the integer. ...
- 给JZ2440开发板重新分区
转自:http://mp.weixin.qq.com/s?__biz=MzAxNTAyOTczMw==&mid=2649328035&idx=1&sn=7d3935cc05d3 ...