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

因为之前的Tarjan模板不够清晰,学习一下熊神的经验,在刷专题之前先整理出一个清晰的模板,方便后面拷贝。

题意清晰,赤裸裸的模板题,就不啰嗦题解了。

/*
 * Author: Haipz
 * School: HDU
 * File Name: 1296.cpp
 */
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cctype>
#include <cfloat>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
using namespace std;

const int N = 10000, M = 100000;
int first[N + 5];
struct edge {
    int v, pre;
} f[M + 5];
int low[N + 5], dfn[N + 5];
int belong[N + 5], inStack[N + 5], Stack[N + 5];
int top, index, bcnt;

void addEdge(int k, int u, int v) {
    f[k].v = v, f[k].pre = first[u], first[u] = k;
    return;
}

void Tarjan(int u) {
    Stack[top++] = u, inStack[u] = 1;
    low[u] = dfn[u] = ++index;
    for (int i = first[u]; i; i = f[i].pre) {
        int v = f[i].v;
        if (dfn[v] == 0) {
            Tarjan(v);
            low[u] = min(low[v], low[u]);
        } else if (inStack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u]){
        ++bcnt;
        int v;
        do {
            v= Stack[--top];
            inStack[v] = 0;
            belong[v] = bcnt;
        } while( u!=v );
    }
}

void init(int n) {
    top = bcnt = index = 0;
    for (int i = 1; i <= n; ++i) belong[i] = i;
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(inStack, 0, sizeof(inStack));
    return;
}

int main() {
    int n, m;
    while (scanf("%d%d", &n, &m), n + m) {
        init(n);
        memset(first, 0, sizeof(first));
        for (int i = 1; i <= m; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            addEdge(i, u, v);
        }
        Tarjan(1);
        if (bcnt == 1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
转载保留版权:http://haipz.com/blog/i/5581 - 海胖博客