首页 > 编程语言 >tarjan算法

tarjan算法

时间:2023-06-04 09:55:49浏览次数:37  
标签:tmp tarjan int dfs 算法 vector low dfn

求强连通分量:

#include <bits/stdc++.h>

using namespace std;

int main() {
  int n, m;
  scanf("%d%d", &n, &m);

  vector<vector<int>> adj(n + 1);
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
  }

  vector<int> dfn(n + 1);  // dfs 森林每个点的时间戳
  vector<int> low(n + 1);  // dfs 森林每个点能跳到的所用点中最小的时间戳
  vector<bool> is_in_stack(n + 1);  // 判断每个点是否在栈中
  vector<int> belong(n + 1);  // 记录每个点属于哪个强连通分量中
  stack<int> stk;  // 存储可能在强连通分量中的点
  int timestamp = 0;  // dfs 时的时间戳
  vector<vector<int>> scc;  // 记录强连通分量
  int cnt = 0;  // 强连通分量的数量

  function <void(int)> dfs = [&](int u) {
    dfn[u] = low[u] = ++timestamp;
    is_in_stack[u] = true;
    stk.push(u);

    for (auto v : adj[u]) {
      if (!dfn[v]) {
        dfs(v);
        low[u] = min(low[u], low[v]);
      } else {
        if (is_in_stack[v]) {
          low[u] = min(low[u], dfn[v]);
        }
      }
    }

    if (dfn[u] == low[u]) {
      ++cnt;
      vector<int> tmp;
      while (true) {
        int v = stk.top();
        tmp.push_back(v);
        belong[v] = cnt;
        is_in_stack[v] = false;
        stk.pop();
        if (v == u) {
          break;
        }
      }
      // 如果需要对强连通分量里的元素排序加此行
      sort(tmp.begin(), tmp.end());
      scc.push_back(std::move(tmp));
    }
  };

  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) {
      dfs(i);
    }
  }
  sort(scc.begin(), scc.end());

  for (auto c : scc) {
    for (auto u : c) {
      printf("%d ", u);
    }
    printf("\n");
  }
}

/*
5 6
1 3
3 1
2 4
4 5
5 2
1 2

ans:
1 3
2 4 5
*/

标签:tmp,tarjan,int,dfs,算法,vector,low,dfn
From: https://www.cnblogs.com/hacker-dvd/p/17455244.html

相关文章

  • 【实验】粒子群算法的超参数优化
    粒子群算法的超参数优化粒子群算法概述粒子群优化算法(ParticleSwarmOptimization)是由美国的Kennedy和Eberhart两位博士提出的一种优化算法。这种算法基于Boid模型。Reynolds通过观察自然界中,鸟类聚集飞行的行为,提出了Boid模型。在Boid中,每个个体是一个Boid,它们各自均可感知......
  • 【实验】遗传算法的超参数优化
    wine数据集分类结果GridSearchbestparameters:{'algorithm':'SAMME','learning_rate':0.3593813663804626,'n_estimators':60}bestscore:0.9720634920634922TimeElapse:113.00295925140381GridSearchBasedGABest......
  • 量子搜索算法
    建议大家去看大佬的原文:量子搜索算法量子搜索算法是什么?假设我们现在有这样一个问题:寻找一个N位的二进制解串:\(X=(x_1x_2...x_n)\),使其满足条件:\(F(X)\leqC\)。其中\(F(X)\)可以是任一函数,\(C\)可以是一个足够小的常数,但保证至少存在一个解满足条件。对于一般情况而言,只能遍......
  • python版本的“共轭梯度法”算法代码
    在看代码的过程中遇到了共轭梯度法这个概念,对这个算法的数学解释看过几遍,推导看过了,感觉懂了,然后过上一些日子就又忘记了,然后又看了一遍推导,然后过了一些日子也就又忘记了,最后想想这个算法的数学解释就不要再取深究了,毕竟平时也不太会用到,偶尔用到了只要保证代码会写也就OK了。  ......
  • 最小二乘法的矩阵正则化改进——“岭回归”和“LASSO回归”算法
    看代码过程中发现了一个很奇怪的概念,叫做“最小二乘法的矩阵正则化”,这个词汇十分的陌生,虽然最小二乘法是知道的,但是用了矩阵正则化的最小二乘法是个什么东西呢?  相关代码见:强化学习:连续控制问题中Actor-Critic算法的linearbaseline  后来在网上一通查才知道,原来“最小二乘法......
  • 强化学习:连续控制问题中Actor-Critic算法的linear baseline
    最近在看连续控制问题,看到了一个Actor-Critic算法中手动扩展features和设置linearbaseline的方法,这些方法源自论文:《BenchmarkingDeepReinforcementLearningforContinuousControl》。  对于低维的features我们可以手动扩展:  代码实现:returntorch.cat([observations,ob......
  • 文心一言 VS 讯飞星火 VS chatgpt (30)-- 算法导论5.2 2题
    二、在HIRE-ASSISTANT中,假设应聘者以随机顺序出现,你正好雇用两次的概率是多少?文心一言:我们可以先计算出在HIRE-ASSISTANT中,雇佣一个应聘者的概率为3/4,然后计算出雇佣两次应聘者的概率为3/4*3/4*2。已知在HIRE-ASSISTANT中,雇佣一个应聘者的概率为:0.75根据概率乘法原理,可计算出......
  • 文心一言 VS 讯飞星火 VS chatgpt (30)-- 算法导论5.2 2题
    二、在HIRE-ASSISTANT中,假设应聘者以随机顺序出现,你正好雇用两次的概率是多少?文心一言:我们可以先计算出在HIRE-ASSISTANT中,雇佣一个应聘者的概率为3/4,然后计算出雇佣两次应聘者的概率为3/4*3/4*2。已知在HIRE-ASSISTANT中,雇佣一个应聘者的概率为:0.75根据概率乘法原理,可......
  • 前置知识:方法递归的算法、执行流程详解
       ......
  • m移动通信系统中越区切换算法的matlab仿真,对比MASN,ASUR,OP
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要硬切换,就是强制切换,其最大的特点是:“先断后连”。在硬切换过程中,用户移动设备仅仅保持与一个基站链接,一旦切换操作被激活,其马上会切断原有的连接,然后再与新的基站建立连接。从一个基站切换到另个基站的过程中,通信......