[知识点]Tarjan算法
// 此博文为迁移而来,写于2015年4月14日,不代表本人现在的观点与看法。原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vxnx.html
UPDATE(20180809):对代码和描述进行大量修改。
UPDATE(20151104):新增Tarjan算法核心代码。




#include <cstdio> #define MAXN 1005
#define MAXM 10005 int o, n, m, u, v, h[MAXN], ins[MAXN], dfn[MAXN], low[MAXN], tim, st[MAXN << ], t, tot, top[MAXN], ans[MAXN][MAXN]; struct Edge {
int v, next;
} e[MAXM]; int min(int a, int b) {
return a < b ? a : b;
} void add(int u, int v) {
o++, e[o] = (Edge) {v, h[u]}, h[u] = o;
} void tarjan(int o) {
dfn[o] = low[o] = ++tim, ins[o] = , st[++t] = o;
for (int x = h[o]; x; x = e[x].next) {
int v = e[x].v;
if (!dfn[v]) tarjan(v), low[o] = min(low[o], low[v]);
else if (ins[v] && dfn[v] < low[o]) low[o] = dfn[v];
}
if (dfn[o] == low[o]) {
int x; tot++;
do {
x = st[t--];
ins[x] = ;
ans[tot][++top[tot]] = x;
} while (x != o);
}
} int main() {
freopen("tarjan.in", "r", stdin);
freopen("tarjan.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) scanf("%d %d", &u, &v), add(u, v);
for (int i = ; i <= n; i++) if (!dfn[i]) tarjan(i);
for (int i = ; i <= tot; i++) {
for (int j = ; j <= top[i]; j++) printf("%d ", ans[i][j]);
printf("\n");
}
return ;
}

#include <cstdio> #define MAXN 500005
#define MAXM 500005 int n, m, u[MAXN], v[MAXN], tw[MAXN], ts, p, to, tb[MAXN], th[MAXN];
int w[MAXN], b[MAXN], s, h[MAXN], o, lik[MAXN];
int dfn[MAXN], low[MAXN], ins[MAXN], st[MAXN], tot, t, tim;
int f[MAXN], ans; struct Edge {
int v, next;
} e[MAXM], te[MAXM]; int min(int a, int b) {
return a < b ? a : b;
} int max(int a, int b) {
return a > b ? a : b;
} void add(int u, int v, int t) {
if (t) to++, te[to] = (Edge) {v, th[u]}, th[u] = to;
else o++, e[o] = (Edge) {v, h[u]}, h[u] = o;
} void init() {
scanf("%d %d", &n, &m);
for (int i = ; i <= m; i++) scanf("%d %d", &u[i], &v[i]), add(u[i], v[i], );
for (int i = ; i <= n; i++) scanf("%d", &tw[i]);
scanf("%d %d", &ts, &p);
for (int i = ; i <= p; i++) scanf("%d", &o), tb[o] = ;
} void tarjan(int o) {
dfn[o] = low[o] = ++tim, ins[o] = , st[++t] = o;
for (int x = th[o]; x; x = te[x].next) {
int v = te[x].v;
if (!dfn[v]) tarjan(v), low[o] = min(low[v], low[o]);
else if (ins[v] && dfn[v] < low[o]) low[o] = dfn[v];
}
if (dfn[o] == low[o]) {
int x; tot++;
do x = st[t--], ins[x] = , lik[x] = tot; while (x != o);
}
} void rebuild() {
for (int i = ; i <= m; i++) if (lik[u[i]] != lik[v[i]]) add(lik[u[i]], lik[v[i]], );
for (int i = ; i <= n; i++) {
w[lik[i]] += tw[i];
if (i == ts) s = lik[i];
if (tb[i]) b[lik[i]] = ;
}
f[s] = w[s];
} void DFS(int o) {
if (b[o]) ans = max(ans, f[o]);
for (int x = h[o]; x; x = e[x].next) {
int v = e[x].v;
if (f[o] + w[v] > f[v]) f[v] = f[o] + w[v], DFS(v);
}
} int main() {
init();
for (int i = ; i <= n; i++) if (!dfn[i]) tarjan(i);
rebuild();
DFS(s);
printf("%d", ans);
return ;
}
[知识点]Tarjan算法的更多相关文章
- tarjan算法 POJ3177-Redundant Paths
参考资料传送门 http://blog.csdn.net/lyy289065406/article/details/6762370 http://blog.csdn.net/lyy289065406/ ...
- 有向图强连通分量的Tarjan算法
有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...
- 点/边 双连通分量---Tarjan算法
运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...
- 割点和桥---Tarjan算法
使用Tarjan算法求解图的割点和桥. 1.割点 主要的算法结构就是DFS,一个点是割点,当且仅当以下两种情况: (1)该节点是根节点,且有两棵以上的子树; (2)该节 ...
- Tarjan算法---强联通分量
1.基础知识 在有向图G,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子 ...
- (转载)LCA问题的Tarjan算法
转载自:Click Here LCA问题(Lowest Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两 ...
- 强连通分量的Tarjan算法
资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...
- Tarjan 算法&模板
Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...
- 【小白入门向】tarjan算法+codevs1332上白泽慧音 题解报告
一.[前言]关于tarjan tarjan算法是由Robert Tarjan提出的求解有向图强连通分量的算法. 那么问题来了找蓝翔!(划掉)什么是强连通分量? 我们定义:如果两个顶点互相连通(即存在A ...
随机推荐
- WebService - 怎样提高WebService性能 大数据量网络传输处理
直接返回DataSet对象 返回DataSet对象用Binary序列化后的字节数组 返回DataSetSurrogate对象用Binary序列化后的字节数组 返回DataSetSurrogate对象用 ...
- 基于Bootstrap简单实用的tags标签插件
http://www.htmleaf.com/jQuery/ jQuery之家 自由分享jQuery.html5和css3的插件库 基于Bootstrap简单实用的tags标签插件
- WebApiのエラーメッセージをどうカスタマイズです?
本来是发布在客户的Wiki上,所以就用日语写. ------------------------------------------------------------------------ Web ...
- POJ2762 Going from u to v or from v to u(单连通 缩点)
判断图是否单连通,先用强连通分图处理,再拓扑排序,需注意: 符合要求的不一定是链拓扑排序列结果唯一,即在队列中的元素始终只有一个 #include<cstdio> #include< ...
- C# 遍历指定目录下的所有文件及文件夹
// DirectoryInfo di = new DirectoryInfo(@"D:\Test"); // FindFile(di); static void FindFile ...
- html5 方框内的小球
html5 方框内的小球 版本一 <!DOCTYPE html> <html> <head lang="en"> <meta charse ...
- Ubuntu下安装Nginx
转载自:http://www.cnblogs.com/skynet/p/4146083.html 1.Nginx安装 我使用的环境是64位 Ubuntu 14.04, Nginx是Nginx 1.10 ...
- bbed的使用--安装及初探
bbed是oracle内部一款用来直接查看和修改数据文件数据的工具,可以直接修改Oracle数据文件块的内容,在一些特殊恢复场景下比较有用. 1.bbed 的安装 在9i/10g中连接生成bbed: ...
- 第三篇:用SOUI能做什么?
SOUI-DEMO界面预览 在回答SOUI能做什么之前,先看看SVN中demo工程的界面截图: 使用SOUI实现上面的界面主要的工作全在配置几个XML文件,基本不需要写C++代码.(如何配置XML布局 ...
- PAT A 1013. Battle Over Cities (25)【并查集】
https://www.patest.cn/contests/pat-a-practise/1013 思路:并查集合并 #include<set> #include<map> ...