zoukankan      html  css  js  c++  java
  • 神仙的Tarjan算法,能否让我完全理解?

    Tips

    • 有向图,缩强连通分量需要判断是否在栈,而无向图不需要。

    求有向图的强连通分量

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int rd(){
    	int res = 0, fl = 1; char c = getchar();
        while(!isdigit(c)){if(c == '-') fl = -1; c = getchar();}
        while(isdigit(c)){res = (res << 3) + (res << 1) + c - '0'; c = getchar();}
        return res * fl;
    }
    const int maxn = 1000010;
    int n, m, en(1), fst[maxn], A, B;
    int dfn[maxn], low[maxn], cnt, stk[maxn], top;
    int bl[maxn], bcc, puted[maxn];
    bool ins[maxn];
    vector<int> Block[maxn];
    struct Edge{
    	int to, nxt;
    }ed[maxn];
    void add(int u, int v){
    	ed[++en].to = v; ed[en].nxt = fst[u]; fst[u] = en; 
    }
    void tarjan(int u){
    	dfn[u] = low[u] = ++cnt;
    	stk[++top] = u;
    	ins[u] = 1;
    	for(int e(fst[u]), v(ed[e].to); e; e = ed[e].nxt, v = ed[e].to){
    		if(!dfn[v]){
    			tarjan(v);
    			low[u] = min(low[u], low[v]);
    		}
    		else if(ins[v]) low[u] = min(low[u], dfn[v]);
    	}
    	if(dfn[u] == low[u]){
    		bcc++;
    		do{
    			bl[stk[top]] = bcc;
    			Block[bcc].push_back(stk[top]);
    			ins[stk[top]] = 0;
    		}while(stk[top--] != u);
    	}
    } 
    int main(){
    	n = rd(); m = rd();
    	for(int i(1); i <= m; ++i){
    		A = rd(); B = rd();
    		add(A, B);
    	}
    	for(int i(1); i <= n; ++i){
    		if(!dfn[i])tarjan(i);
    	}
    	printf("%d
    ", bcc);
    	for(int i(1); i <= n; ++i){
    		if(!puted[bl[i]]){
    			sort(Block[bl[i]].begin(), Block[bl[i]].end());
    			int len = Block[bl[i]].size(); 
    			for(int j(0); j < len; ++j){
    				printf("%d ", Block[bl[i]][j]);
    			} printf("
    ");
    			puted[bl[i]] = 1;
    		}
    	}
    	return 0;
    }
    
    

    无向图如何找出割边?

    单纯找割边的话完全用不到栈。

    void Tarjan(int u, int fa){
    	dfn[u] = low[u] = ++cnt;
    	for(int e(fst[u]), v(ed[e].to); e; e = ed[e].nxt, v = ed[e].to){
    		if((v == fa) || (v == u)) continue;
    		if(!dfn[v]){
    			Tarjan(v, u);
    			low[u] = min(low[u], low[v]);
    			if(low[v] > dfn[u]) Ans[++tot] = e; 
    		}
    		else low[u] = min(low[u], dfn[v]);
    	}
    }
    
  • 相关阅读:
    Python使用 odbc、jdbc与 Object Relational Mapping (ORM)进行数据库开发
    Tensorflow安装
    学生作业
    大学课程推荐
    人工智能的开发工具
    android开发
    jdbc-odbc桥
    开博随记
    利用jq实现自适应边缘情况的气泡Tip
    一篇完整的FlexBox布局指南
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/15335620.html
Copyright © 2011-2022 走看看