Tarjan算法初探(2):缩点
接上一节 Tarjan算法初探(1):Tarjan如何求有向图的强连通分量
Tarjan算法一个非常重要的应用就是 在一张题目性质在点上性质能够合并的普通有向图中将整个强连通分量视作一个点来把整张图变成一张DAG(即有向无环图) 而DAG的形态满足最优子结构经常与DP联系在一起 故缩点常作为一条桥梁将图论与DP相联系
缩点思想不难理解 这里主要说明一下代码的操作细节与流程:
1.使用Tarjan算法求出每个点属于哪一个强连通分量
2.枚举每一条点将每一个点对应性质合并到新的点上
3.枚举每一条边将每条边两端的点对应的新点相连来重构整张图(注意自环的问题) 重构时可能有的重边不影响重构图是一个DAG
其中 2 3 步可同时进行。
下面贴一道模板题来熟悉代码
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。 n<=10^4,m<=10^5,0<=点权<=1000
分析:
裸题 缩点以后直接DP完事 没有思维难度的DP
#include <cstdio>
#include <iostream>
#define re register
#define r(x) x=read()
#define MAXX 10005
#define MIN(a,b) (a<b?a:b)
#define MAX(a,b) (a>b?a:b)
using namespace std;
int dfn[MAXX],low[MAXX],que[MAXX],ans[MAXX],w[MAXX],w2[MAXX],id[MAXX],
st[MAXX],top,u,to,n,m,cnt[],k,num,h[][MAXX],sum[MAXX];
struct edge{int to,nex;}e[][MAXX<<];
void add(int u,int to,int id)
{
++cnt[id];
e[id][cnt[id]]=(edge){to,h[id][u]};
h[id][u]=cnt[id];
}
int read()
{
char ch=;int w=,ff=;
while(ch<''||ch>''){if(ch=='-')ff=-;ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return ff*w;
}
void tarjan(int now)//求强连通分量
{
low[now]=dfn[now]=++k;
st[++top]=now;
for(int i=h[][now];i;i=e[][i].nex)
{
if(!dfn[e[][i].to])
tarjan(e[][i].to),low[now]=MIN(low[now],low[e[][i].to]);
else
if(!id[e[][i].to])
low[now]=MIN(low[now],dfn[e[][i].to]);
}
if(low[now]==dfn[now])
{
id[now]=++num;
while(st[top]!=now)
{
id[st[top]]=num;
--top;
}
--top;
}
}
void build()//缩点
{
for(int i=;i<=n;++i)
{
w2[id[i]]+=w[i];//点权值合并
for(int j=h[][i];j;j=e[][j].nex)
if(id[i]!=id[e[][j].to])
add(id[i],id[e[][j].to],),++sum[id[e[][j].to]];//连边
}
for(int i=;i<=num;++i)
if(sum[i]==) que[++top]=i,ans[que[top]]+=w2[que[top]];
for(int i=;i<=top;++i)
{
for(int j=h[][que[i]];j;j=e[][j].nex)
{
sum[e[][j].to]--;
if(!sum[e[][j].to]) que[++top]=e[][j].to;
}
}//拓扑排序
}
void solve()//裸DP
{
for(int i=;i<=top;++i)
for(int j=h[][que[i]];j;j=e[][j].nex)
ans[e[][j].to]=MAX(ans[e[][j].to],w2[e[][j].to]+ans[que[i]]);
int maxx=;
for(int i=;i<=num;++i)
maxx=max(maxx,ans[i]);
printf("%d",maxx);
}
void input()
{
r(n),r(m);
for(re int i=;i<=n;++i)
r(w[i]);
for(re int i=;i<=m;++i)
r(u),r(to),add(u,to,);
}
int main()
{
input();
for(re int i=;i<=n;++i)
if(!id[i])
tarjan(i);
build();
solve();
return ;
}
Tarjan算法初探(2):缩点的更多相关文章
- Tarjan算法初探(3):求割点与桥以及双连通分量
接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的 ...
- Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...
- tarjan算法求scc & 缩点
前置知识 图的遍历(dfs) 强连通&强连通分量 对于有向图G中的任意两个顶点u和v存在u->v的一条路径,同时也存在v->u的路径,我们则称这两个顶点强连通.以此类推,强连通分量 ...
- poj1236 Network of Schools ,有向图求强连通分量(Tarjan算法),缩点
题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点.才干做到从这些顶点出发,能够到达所有顶点 2) 至少要加多少条边.才干使得从不论什么一个顶点出发,都能到达所有顶点 ...
- POJ 2762 Going from u to v or from v to u? Tarjan算法 学习例题
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17104 Accepted: 4594 Description In o ...
- 图之强连通--Tarjan算法
强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components ...
- Tarjan算法 求 有向图的强连通分量
百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)
这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...
随机推荐
- 【Android Studio使用教程1】Android Studio导入项目的几种方法
本篇教程中使用到的Android Studio版本为1.0, Eclipse ADT版本23.0.4.请尝试更新到该版本. Android Studio默认使用 Gradle 构建项目, Eclips ...
- gulp 在 angular 项目中的使用
gulp 在 angular 项目中的使用 keyword:gulp,angularjs,ng,ngAnnotate,jshint,gulpfile 最后附完整简洁的ng项目gulpfile.js 准 ...
- DOM介绍
什么是DOM DOM:文档对象模型.DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构.目的其实就是为了能让js操作html元素而制定的一个规范. DOM就是由节点组成的. 解析过程 ...
- [翻译] PQFCustomLoaders
PQFCustomLoaders Current version: 0.0.1 Collection of highly customizable loaders for your iOS proje ...
- Python初学者第十二天 购物车程序小作业
12day 作业题目: 购物车程序 作业需求: 数据结构: goods = [ {"name": "电脑", "price": 1999}, ...
- Druid学习---配置_DruidDataSource参考配置
[更多参考]https://www.cnblogs.com/niejunlei/p/5977895.html 配置_DruidDataSource参考配置 以下是一个参考的连接池配置: <bea ...
- Linux telnet命令详解
telnet命令通常用来远程登录.telnet程序是基于TELNET协议的远程登录客户端程序.Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户 ...
- 【Oozie】ambari安装oozie失败
之前对azkaban的研究比较多,现在开个新坑,对Oozie开始深入了解 Traceback (most recent call last): File "/var/lib/ambari-a ...
- 关于memcpy的实现
今天去面试,面试官出了一个关于memcpy的函数原型的实现的问题,本来这个问题是很简单的,但是不知道当时怎么脑子一抽竟然写错了,真是”累觉不爱”了.感觉这份工作算是泡汤了,算了事情发生了,错过了也就错 ...
- 本机未装Oracle数据库时Navicat for Oracle 报错:Cannot create oci environment 原因分析及解决方案
因为要更新数据库加个表,远程桌面又无法连接...所以就远程到另外一台电脑,然后用navicat通过内网修改目标数据库. 一直用着navicat操作数据库,所以很速度的弄好然后新建连接进入数据库. 然而 ...