求有向图强连通分量:Trajan算法模板

因为一次考试中一道题涉及到2-SAT,2-SAT又涉及到强连通分量TAT,于是怒学;
对于此算法的讲解:
参见byvoid博客;
(以下样例中用图也来自此blog)

自己测试用样例(输出每个节点所在的scc):
对应的图片
trajan.in
6 8
1 3
1 2
2 4
3 4
3 5
4 1
4 6
5 6
trajan.out
3 3 3 3 2 1
自己打的一个小模板:

#include
#include
#include
#include
#include
using namespace std;
#define maxn 100 + 10
#define maxm 10000 + 10
#define INF 0x7f7f7f7f
int front[maxn], dfn[maxn], low[maxn], belong[maxn], que[maxn]; bool vis[maxn];
int n, m, cur, scc, index, top;
struct edge{
    int to, next;
}e[maxm];
inline void addedge(int u, int v){
    e[++ cur].to = v; e[cur].next = front[u]; front[u] = cur;
}
inline void trajan(int u){
    dfn[u] = low[u] = ++ index;
    que[++ top] = u; vis[u] = 1;
    for(int i = front[u]; i; i = e[i].next)
        if(!dfn[e[i].to])
            trajan(e[i].to), low[u] = min(low[u], low[e[i].to]);
        else if(vis[e[i].to])
            low[u] = min(low[u], dfn[e[i].to]);
    int now = -1;
    if(low[u] == dfn[u]){
        scc++;
        while(now != u){
            now = que[top --];
            belong[now] = scc;
            vis[now] = 0;
        }
    }
}
int main(){
    freopen("trajan.in","r",stdin); freopen("trajan.out","w", stdout);
    cur = scc = top = index = 0;
    memset(dfn, 0, sizeof(dfn));
    scanf("%d%d", &n, &m);
    while(m --){
        int u, v; scanf("%d%d",&u, &v);
        addedge(u,v);
    }
    for(int i = 1; i <= n; i ++)
        if(!dfn[i]) trajan(i);
    for(int i = 1; i <= n; i ++)
        printf("%d%c", belong[i], (i == n) ? '\n' : ' ');
    fclose(stdin); fclose(stdout);
    return 0;
}

你可能感兴趣的:(模板,图的连通)