Tarjan 的应用
来源:互联网 发布:手机编曲软件中文版 编辑:程序博客网 时间:2024/05/22 01:50
Tarjan
在有/无向图中,如果两个节点可以相互到达,则称这两个节点强连通[Strongly
connected],如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量 [Strongly connected components]
Tarjan 的发明者Robert Tarjan是 一位伟大的计算机科学家。他发明的LCA,Tarjan 知道现在一直都是数据结构的基础根基。由于他杰出的贡献 ,让他也同样获得了计算机界的诺贝尔奖——图灵奖。
但究竟什么是 强连通分量?什么是强连通图?很多人都爱用下面的图。。。
虽然很丑。不过说明了一些 本质?
还是下面的比较好
Graph 1 就是一个强连通图,因为这4个点可以两两任意 相互到达。但是Graph 2 就不是因为 4 不能到达其余任意一个点。
Algorithm:
在我看来,Tarjan 就是一个很 玄学的东西。甚至不需要你去理解为什么要这么做,把代码记熟,要求的东西都能求出来了。但还是说说吧。
Tarjan算法是基于对图深度优先搜索的算法。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。
具体见代码:
Code:
void Tarjan(int rt){ dfn[rt]=low[rt]=++dep; stack[++top]=rt; for(int i=head[i];i!=-1;i=edge[i].next) { int v=edge[i].to; if(dfn[to]==0) { Tarjan(to);; low[rt]=min(low[rt],low[to]); } if(belong[to]==0) { low[rt]=min(low[rt],dfn[to]); } } if(low[rt]==dfn[to]) { scc_cnt++; int t=0,v; do { t++; v=stack[top--]; belong[v]=scc_cnt; }while(v!=rt); scc_num[scc_cnt]=t; }}
- scc_cnt表示图中的强连通块的个数
- belong[i]表示i点所在强连通图中的编号
scc_num[i]表示第i号强连通图 中的元素个数
对于无向图的Tarjan大同小异,只要多传一个变量记录rt的父亲节点就好了、同时多了一些概念比如 割点、割边(桥)。但也十分简单 。
应用
Tarjan 的应用十分广泛 。除了在强联通图中的一些性质外,它还可以判断确定某些集合关系。
☀举个例子,K国有N个地区,每个地区间可以免费通行,而到别的地区就需要花费相应的代价。现在想让你求从ST到 ED间的最短路时就不能简单用Dijkstra或者SPFA。而需要先Tarjan缩点后重新建图,再跑最短路。
☀Tarjan 的另一个应用就是有关度的 应用:
在有向图中,如果给定N个人以及中的M个关系。然后现在让你确定一个/些点让它与其它各点都有关系。而我们的解决方法就是先缩点,把能够 互相到达[即与本集合中的点都有关系]的点缩成一个点。然后出度为0的集合中的点就是我们要求的答案。
☀无向图中的双联通分量中也有很多应用:比如删掉一个点让连通图的数量最大。那么显然删掉 割点 就可以了。
☀有的时候,问题可能没有那么明显:USACO中有一道题,求的是在一张无向图中,最少加几条边,能让任意两点间,至少有两条不重复的路径相互到达。乍一看可能不知道该怎么想,但是随着分析的深入我们会发现,在一个双联通分量图中,任意两个点都有两条路径相互到达。所以我们就可以把这道题转化为 最少加入多少边让图变成 边-双。
而我们的解决方法 就是在缩点之后把入度为1的点集计数[sum],(sum+1)/2 就是答案。
☀//首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
☀还有就是可以用 Tarjan 离线求LCA。
。。。 。。。
小结
总之,Tarjan 就是解决 图论问题的一种方法而已。或者说Tarjan只是我们简化问题的一种手段。真正考验我们的不是怎么去写代码,而是怎么通过各种手段简化问题,让数据范围更容易接受。这才是我们开发算法,编程的目的 。
- Tarjan 的应用
- 关于tarjan算法的应用
- uva 610(tarjan的应用)
- 总结 Tarjan的一些应用
- poj 2553 (tarjan的应用)
- tarjan在acm里的应用
- lightoj 1168-Wishing Snake(Tarjan的应用)
- loj 1168(Tarjan应用)
- tarjan模板及应用
- hdu 3836,tarjan算法的应用(有向图缩点)
- Tarjan应用:无向图删点后剩余的连通分支数目
- poj-2186 受欢迎的奶牛(tarjan算法应用)
- 强连通分量的tarjan算法应用(一)
- codeforces864F Cities Excursions 图论,tarjan算法的应用
- Tarjan算法的改装
- tarjan算法的实现
- tarjan算法的心得
- LCA的Tarjan算法
- 安装黑苹果Mac和Windows双系统之后的时间同步
- 计算机网络 - 物理层
- 接口的想法
- Android+PHP 使用HttpClient提交POST的请求,使用JSON解析响应
- 【多题合集】【loliの模拟赛】排列组合大套餐
- Tarjan 的应用
- 音乐播放器-Activities
- CodeForces 400A Inna and Choose Options
- C++实现的屏幕截图(PNG或BMP)
- NSUserDefaults SQLite CoreData
- 牛客堂刷题(常见面试题精讲)之矩阵打印
- IE7浏览器下CSS属性选择器二三事
- NSURLCache 2 内存缓存
- Java命名规范与注释规范