• 图论--SCC缩点--Tarjan


    // Tarjan算法求有向图强连通分量并缩点
    /*强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作。*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N = 100010, M = 1000010;
    int ver[M], Next[M], head[N], dfn[N], low[N];
    int stack[N], ins[N], c[N];
    int vc[M], nc[M], hc[N], tc;
    vector<int> scc[N];
    int n, m, tot, num, top, cnt;
     
    void add(int x, int y) {
    	ver[++tot] = y, Next[tot] = head[x], head[x] = tot;
    }
     
    void add_c(int x, int y) {
    	vc[++tc] = y, nc[tc] = hc[x], hc[x] = tc;
    }
     
    void tarjan(int x) {
    	dfn[x] = low[x] = ++num;
    	stack[++top] = x, ins[x] = 1;
    	for (int i = head[x]; i; i = Next[i])
    		if (!dfn[ver[i]]) {
    			tarjan(ver[i]);
    			low[x] = min(low[x], low[ver[i]]);
    		}
    		else if (ins[ver[i]])
    			low[x] = min(low[x], dfn[ver[i]]);
    	if (dfn[x] == low[x]) {
    		cnt++; int y;
    		do {
    			y = stack[top--], ins[y] = 0;
    			c[y] = cnt, scc[cnt].push_back(y);
    		} while (x != y);
    	}
    }
     
    int main() {
    	cin >> n >> m;
    	for (int i = 1; i <= m; i++) {
    		int x, y;
    		scanf("%d%d", &x, &y);
    		add(x, y);
    	}
    	for (int i = 1; i <= n; i++)
    		if (!dfn[i]) tarjan(i);
    	for (int x = 1; x <= n; x++)
    		for (int i = head[x]; i; i = Next[i]) {
    			int y = ver[i];
    			if (c[x] == c[y]) continue;
    			add_c(c[x], c[y]);
    		}
    }
  • 相关阅读:
    MongoDB 之 手把手教你增删改查 MongoDB
    MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB
    全栈12期的崛起之捡点儿有用的说说
    Python 常用模块
    Python3中的内置函数
    Python程序员之面试必回习题
    Django之初始庐山真面目
    Django之ORM操作
    MySQL-索引
    MySQL-函数
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798655.html
Copyright © 2020-2023  润新知