hdu 1269 迷宫城堡(trajan判环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269

题意:略

题解:trajan模版直接求强连通分量。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
struct Edge {
    int v , next;
}edge[M];
int head[N] , e;
int Low[N] , DFN[N] , Stack[N] , Belong[N];
int Index , top;
int scc;
bool Instack[N];
int num[N];
void init() {
    e = 0;
    memset(head , -1 , sizeof(head));
}
void add(int u , int v) {
    edge[e].v = v , edge[e].next = head[u] , head[u] = e++;
}
void Tarjan(int u) {
    int v;
    Low[u] = DFN[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    for(int i = head[u] ; i != -1 ; i = edge[i].next) {
        v = edge[i].v;
        if(!DFN[v]) {
            Tarjan(v);
            Low[u] = min(Low[u] , Low[v]);
        }
        else if(Instack[v]) Low[u] = min(Low[u] , DFN[v]);
    }
    if(Low[u] == DFN[u]) {
        scc++;
        do {
            v = Stack[--top];
            Instack[v] = false;
            Belong[v] = scc;
            num[scc]++;
        }
        while(v != u);
    }
}
int main() {
    int a , b , n , m;
    while(scanf("%d%d" , &n , &m) != EOF) {
        if(n == 0 && m == 0) break;
        init();
        for(int i = 0 ; i < m ; i++) {
            scanf("%d%d" , &a , &b);
            add(a , b);
        }
        memset(DFN , 0 , sizeof(DFN));
        memset(Instack , false , sizeof(Instack));
        memset(num , 0 , sizeof(num));
        Index = scc = top = 0;
        for(int i = 1 ; i <= n ; i++)
            if(!DFN[i]) Tarjan(i);
        if(scc == 1) printf("Yes
");
        else printf("No
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6875156.html