强连通tarjan模版

 时间复杂度为O(n+m)

黑匣子:

先最初调用

1、init()

2、把图用add 存下来,注意图点标为1-n,若是[0,n-1]则给所有点++;

3、调用tarjan_init(n); 再调用suodian();

4、新图就是vector<int>G[];  新图点标从1-tar ;

5、对于原图中的每个点u,都属于新图中的一个新点Belong[u];

新图一定是森林。

6、新图中的点u 所表示的环对应原图中的vector<int> bcc[u];

7、旧图中u在新图中所属的点是Belong[u];

#define N 30100
//N为最大点数
#define M 150100
//M为最大边数
int n, m;//n m 为点数和边数

struct Edge{
	int from, to, nex;
	bool sign;//是否为桥
}edge[M<<1];
int head[N], edgenum;
void add(int u, int v){//边的起点和终点
	Edge E={u, v, head[u], false};
	edge[edgenum] = E;
	head[u] = edgenum++;
}

int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)
int taj;//连通分支标号,从1开始
int Belong[N];//Belong[i] 表示i点属于的连通分支
bool Instack[N];
vector<int> bcc[N]; //标号从1开始

void tarjan(int u ,int fa){  
	DFN[u] = Low[u] 
  • 19
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Tarjan算法是一种基于深度优先搜索的连通分量(SCC)算法。它可以用于在有向图中找到所有的连通分量。 以下是一个使用Matlab实现Tarjan算法的示例: ```matlab function SCC = tarjanAlgorithm(adjMatrix) n = size(adjMatrix, 1); % 获取图的顶点数 index = 1; % 初始化索引 indices = zeros(n, 1); % 顶点的访问索引 lowlinks = zeros(n, 1); % 顶点的最低访问索引 onStack = false(n, 1); % 记录顶点是否在栈中 stack = []; % 存储顶点的栈 SCC = {}; % 存储连通分量 function strongconnect(v) indices(v) = index; % 设置顶点的访问索引 lowlinks(v) = index; % 设置顶点的最低访问索引 index = index + 1; stack = [stack, v]; % 将顶点压入栈中 onStack(v) = true; % 对v的邻接顶点进行递归处理 for w = 1:n if adjMatrix(v, w) == 1 % 如果v和w之间有边 if indices(w) == 0 % 如果w还未被访问过 strongconnect(w); lowlinks(v) = min(lowlinks(v), lowlinks(w)); % 更新v的最低访问索引 elseif onStack(w) % 如果w在栈中 lowlinks(v) = min(lowlinks(v), indices(w)); % 更新v的最低访问索引 end end end % 如果v是一个连通分量的根节点 if lowlinks(v) == indices(v) scc = []; w = -1; while w ~= v w = stack(end); stack = stack(1:end-1); onStack(w) = false; scc = [scc, w]; end SCC{end+1} = scc; end end % 对每个未访问过的顶点进行处理 for v = 1:n if indices(v) == 0 strongconnect(v); end end end ``` 这是一个递归实现的Tarjan算法。你可以将邻接矩阵作为输入参数传递给`tarjanAlgorithm`函数,并且它将返回一个包含所有连通分量的单元格数组`SCC`。 希望这个示例能帮助到你!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值