P3387 【模板】缩点 题解 (Tarjan)
题目链接
解题思路
这几天搞图论,好有趣hhh,多写几篇博客。
上次学\(Tarjan\)求割点,这次缩点。
思路大概是多一个栈和染色的步骤,每次\(Tarjan\)的时候把点入栈,如果某个点(比较像割点但不完全是)的\(DFS\)子树都搜不到它祖宗,那么接下来进行的遍历操作必然与该点不能形成强连通分量,所以可以遇到\(low[p]==dfn[p]\)的点就把栈里面的东西全弹出来,染色表示这是一个强连通分量。
对于这个题,强连通分量之间再进行连边,记忆化搜索(类似树形DP)即可。
AC代码
#include<stdio.h>
#include<string.h>
#define N 100010
#define M 10010
#define min(a,b) (a>b?b:a)
#define max(a,b) (a<b?b:a)
int n,m;
int v[M],x[N],y[N];
struct Edge{
int end,near;
}e[N];
int head[M],cnt;
void add(int a,int b){
e[++cnt].end=b;
e[cnt].near=head[a];
head[a]=cnt;
}
int dfn[M],tot,sta[M],top,vis[M],low[M];
int color[M],num,val[M];
void tarjan(int p){
dfn[p]=low[p]=++tot;
sta[++top]=p;vis[p]=1;
int i;
for(i=head[p];i;i=e[i].near){
int q=e[i].end;
if(!dfn[q])tarjan(q),low[p]=min(low[p],low[q]);
else if(vis[q])low[p]=min(low[p],low[q]);
}
if(dfn[p]==low[p]){
num++;
while(sta[top+1]!=p){
color[sta[top]]=num;
vis[sta[top]]=0;
val[num]+=v[sta[top]];
top--;
}
}
}
int f[M];
void dp(int p){
int i;
for(i=head[p];i;i=e[i].near){
int q=e[i].end;
if(!f[q])dp(q);
f[p]=max(f[p],f[q]);
}
f[p]+=val[p];
}
int main(){
int i,ans=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d",&v[i]);
for(i=0;i<m;i++)scanf("%d%d",&x[i],&y[i]),add(x[i],y[i]);
for(i=1;i<=n;i++)
if(!dfn[i])tarjan(i);//tarjan缩点
memset(head,0,sizeof(head));cnt=0;//清空边
for(i=0;i<m;i++)//强连通分量之间连边
if(color[x[i]]^color[y[i]])add(color[x[i]],color[y[i]]);
for(i=1;i<=num;i++)if(!f[i])dp(i),ans=max(ans,f[i]);//DP
printf("%d",ans);
return 0;
}
P3387 【模板】缩点 题解 (Tarjan)的更多相关文章
- 洛谷P3387 【模板】缩点 题解
背景 今天\(loj\)挂了,于是就有了闲情雅致来刷\(luogu\) 题面 洛谷P3387 [模板]缩点传送门 题意 给定一个\(n\)个点\(m\)条边有向图,每个点有一个权值,求一条路径,使路径 ...
- 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)
Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...
- 【模板】缩点(Tarjan算法)/洛谷P3387
题目链接 https://www.luogu.com.cn/problem/P3387 题目大意 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之 ...
- Tarjan+topsort(DP)【P3387】 [模板]缩点
Description 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次 ...
- 【Luogu】P3387缩点(Tarjan缩点+深搜DP)
题没什么好说的,因为是模板题.求值我用的是dfs. 不能直接在原图上dfs,因为原图上有环的话会发生一些滑稽的事情.所以我们要用Tarjan缩点.因为此题点权全为正,所以如果在图上走一个环当然可以全走 ...
- POJ 2553 The Bottom of a Graph Tarjan找环缩点(题解解释输入)
Description We will use the following (standard) definitions from graph theory. Let V be a nonempty ...
- Luogu3387 缩点 【tarjan】【DP】
Luogu3387 缩点 题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点, ...
- poj3694+hdu2460 求桥+缩点+LCA/tarjan
这个题使我更深理解了TARJAN算法,题意:无向图,每添加一条边后文桥的数量,三种解法:(按时间顺序),1,暴力,每每求桥,听说这样能过,我没过,用的hash判重,这次有俩个参数(n->10w, ...
- P1177 【模板】快速排序 题解
本质为sort,这里我们用优先队列(堆)解决. 什么是堆? 堆 堆是一个完全二叉树,而且是每层都有规律的二叉树 规律大概是: 小根堆:最上层数的大小最小,往下每层结点都比父亲结点大,比两个儿子结点小 ...
随机推荐
- Celery&Flower文档笔记
1.Celery # tasks.py from celery import Celery app = Celery('tasks', broker='redis://localhost:6379', ...
- JS编程练习:将目标节点内部的子节点逆序
将目标节点内部的子节点逆序 1 <body> 2 <div> 3 <p></p> 4 <span></span> 5 <e ...
- JVM 报 GC Overhead limit exceeded 是什么意思?
默认情况下,并不是等堆内存耗尽,才会报 OutOfMemoryError,而是如果 JVM 觉得 GC 效率不高,也会报这个错误. 那么怎么评价 GC 效率不高呢?来看下源码: 呢?来看下源码gcOv ...
- Java开发工程师最新面试题库系列——Java基础部分
JAVA基础 面向对象有哪些特征? 答:继承.封装.多态 JDK与JRE的区别是什么? 答:JDK是java开发时所需环境,它包含了Java开发时需要用到的API,JRE是Java的运行时环境,JDK ...
- SVG in Action
SVG in Action HTML5 semantic HTML5 Semantic Elements / HTML5 Semantic Tags figure object <figure& ...
- XSS (跨站脚本攻击) 的原理分析,测试 && 应对措施
1 1 1 XSS (跨站脚本攻击) 的原理分析,测试 1 demo: <!DOCTYPE html> <html lang="en"> <head& ...
- git config [section] solutions
git config [section] solutions fix git [section] warnings global config $ vim ~/.gitconfig [user] em ...
- nvm install node error
nvm install node error ➜ mini-program-all git:(master) nvm install 10.15.3 Downloading and installin ...
- tslint 忽略对某行代码的检测
tslint rules class Ajanuw { constructor() { console.log("hello ajanuw"); } } // @ts-ignore ...
- 数据序列化工具——flatbuffer
flatbuffer是一款类似于protobuf的数据序列化工具.所有数据序列化,简单来说,就是将某程数据结构按照一定的格式进行编码与解码,以方便在不同的进程间传递后,能够正确的还原成之前的数据结构. ...