题目背景

缩点+DP

题目描述

给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。

允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。

输入输出格式

输入格式:

第一行,n,m

第二行,n个整数,依次代表点权

第三至m+2行,每行两个整数u,v,表示u->v有一条有向边

输出格式:

共一行,最大的点权之和。

输入输出样例

输入样例#1: 复制

2 2
1 1
1 2
2 1

输出样例#1: 复制

2

说明

n<=104,m<=105,|点权|<=1000 算法:Tarjan缩点+DAGdp`

如题,DAG图dp有一个很显然的思路--拓扑排序

#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm> const int maxn = 100007;
int vul[maxn];
struct node{
int v,next;
}edge[maxn*5],edge1[maxn*5];
int head1[maxn],num1;
int head[maxn],num;
void add_edge(int u,int v) {
edge[++num].v=v;edge[num].next=head[u];head[u]=num;
}
void add_edge1(int u,int v) {
edge1[++num1].v=v;edge1[num1].next=head1[u];head1[u]=num1;
}
int n,m,cnt =0,dfn[maxn],low[maxn];bool vis[maxn];
int stack[maxn],top=0;
int vulue[maxn],sum,belong[maxn];
void tarjan(int x) {
low[x]=dfn[x]=++cnt;stack[++top]=x;
vis[x]=1;
for(int i=head[x];i;i=edge[i].next) {
int v=edge[i].v;
if(vis[v]) {
low[x]=std::min(low[x],dfn[v]);
}
else if(!dfn[v]){
tarjan(v);
low[x]=std::min(low[x],low[v]);
}
}
if(low[x]==dfn[x]) {
sum++;
belong[x]=sum;
vulue[sum]+=vul[x];
for(;stack[top]!=x;top--) {
belong[stack[top]]=sum;vis[stack[top]]=0;
vulue[sum]+=vul[stack[top]];
}
vis[x]=0; top--;
}
}
int rd[maxn];
int q[maxn],vull[maxn];
void top_sort(){
int h=1,tail=0;
for(int i=1;i<=sum;++i)
if(rd[i]==0) vull[i]=vulue[i],q[++tail]=i;
while(h<=tail) {
int x=q[h++];
for(int i=head1[x];i;i=edge1[i].next) {
int v=edge1[i].v;
if(rd[v]) {
vull[v]=std::max(vull[v],vull[x]+vulue[v]);
rd[v]--;
if(rd[v]==0) q[++tail]=v;
}
}
}
int ans=0;
for(int i=1;i<=sum;++i)
ans=std::max(ans,vull[i]);
printf("%d\n",ans);
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&vul[i]);
for(int a,b,i=1;i<=m;++i) {
scanf("%d%d",&a,&b);
add_edge(a,b);
}
for(int i=1;i<=n;++i)
if(!dfn[i])tarjan(i);
for(int i=1;i<=n;++i)
for(int j=head[i];j;j=edge[j].next) {
int v=edge[j].v;
if(belong[v]!=belong[i]) {
add_edge1(belong[i],belong[v]);
rd[belong[v]]++;
}
}
top_sort();
return 0;
}

Tarjan缩点+DAG图dp的更多相关文章

  1. [SDOI2010] 所驼门王的宝藏 [建图+tarjan缩点+DAG dp]

    题面传送门: 传送门 思路: 看完题建模,容易得出是求单向图最长路径的问题 那么把这张图缩强联通分量,再在DAG上面DP即可 然而 这道题的建图实际上才是真正的考点 如果对于每一个点都直接连边到它所有 ...

  2. 洛谷 P2656 (缩点 + DAG图上DP)

    ### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...

  3. bzoj1093: [ZJOI2007]最大半连通子图 scc缩点+dag上dp

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

  4. BZOJ5017 [Snoi2017]炸弹[线段树优化建边+scc缩点+DAG上DP/线性递推]

    方法一: 朴素思路:果断建图,每次二分出一个区间然后要向这个区间每个点连有向边,然后一个环的话是可以互相引爆的,缩点之后就是一个DAG,求每个点出发有多少可达点. 然后注意两个问题: 上述建边显然$n ...

  5. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

    题目 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G ...

  6. [ZJOI2007]最大半连通子图 (Tarjan缩点,拓扑排序,DP)

    题目链接 Solution 大概是个裸题. 可以考虑到,如果原图是一个有向无环图,那么其最大半联通子图就是最长的一条路. 于是直接 \(Tarjan\) 缩完点之后跑拓扑序 DP就好了. 同时由于是拓 ...

  7. UVA 11324 The Largest Clique(强连通分量+缩点DAG的DP)

    题意:给定一个有向图,求出一个最大的结点集,这个节点集中的随意两个点之间至少一个能到达还有一个点. 思路:假设一个点在这个节点集中,那么它所在的强连通分量中的点一定所有在这个节点集中,反之亦然, 求出 ...

  8. 【Luogu】P3387缩点(Tarjan缩点+深搜DP)

    题没什么好说的,因为是模板题.求值我用的是dfs. 不能直接在原图上dfs,因为原图上有环的话会发生一些滑稽的事情.所以我们要用Tarjan缩点.因为此题点权全为正,所以如果在图上走一个环当然可以全走 ...

  9. poj2186Popular Cows+tarjan缩点+建图

    传送门: 题意: 给出m条关系,表示n个牛中的崇拜关系,这些关系满足传递性.问被所有牛崇拜的牛有几头: 思路: 先利用tarjan缩点,同一个点中的牛肯定就是等价的了,建立新的图,找出其中出度为0的点 ...

随机推荐

  1. TCP的三次握手和四次握手

    三次握手(建立连接) 首先,服务器进程(B)先创建传控制块TCB(用来存储连接信息,如连接表,发送和接收序号等),准备接收客户进程(A)的请求.然后服务器进程处于LISTEN(收听)状态,等待客户的连 ...

  2. Linux学习-SRPM 的使用 : rpmbuild (Optional)

    新版的 rpm 已经 将 RPM 与 SRPM 的指令分开了,SRPM 使用的是 rpmbuild 这个指令,而不是 rpm 喔! 利用默认值安装 SRPM 文件 (--rebuid/--recomp ...

  3. LA 7056 Colorful Toy Polya定理

    题意: 平面上给出一个\(N\)个点\(M\)条边的无向图,要用\(C\)种颜色去给每个顶点染色. 如果一种染色方案可以旋转得到另一种染色方案,那么说明这两种染色方案是等价的. 求所有染色方案数 \( ...

  4. java append方法

    JAVA 中 Stringbuffer 有append()方法  Stringbuffer其实是动态字符串数组  append()是往动态字符串数组添加,跟“xxxx”+“yyyy”相当那个‘+’号  ...

  5. ES6 异步编程之一:Generator

    Generator 生成器是es6原生提供的异步编程方案,其语法行为和传统函数完全不同,阮大的<ECMAScript 6 入门>一书中对生成器有比较详尽的介绍,还有一些其他的文章可以参考, ...

  6. 连通图 poj2186 最受欢迎的牛(求最受欢迎的牛的数量)

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27531   Accepted: 11077 De ...

  7. HashMap源码分析jdk1.6

    HashMap数组每个元素的初始值为NULL  1.定义 public interface Map<K,V> { int size(); boolean isEmpty(); boolea ...

  8. 设计模式(八)组合模式 Composite

    组合模式: 允许你将对象组合成树形结构来表现“整体/部分”层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合. 从 ...

  9. iOS-----openGL--openGL ES iOS 入门篇--->搭建openGL环境

    OpenGL版本 iOS系统默认支持OpenGl ES1.0.ES2.0以及ES3.0 3个版本,三者之间并不是简单的版本升级,设计理念甚至完全不同,在开发OpenGL项目前,需要根据业务需求选择合适 ...

  10. Swift 3:新的访问控制fileprivate和open

    在swift 3中新增加了两种访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...