CQUoj 威尼斯平底渔船 (强连通)

http://acm.cqu.edu.cn/oj/problem_show.php?pid=21461

建图,判断该图中是否有回路(即强连通),有则输出“Yes”,否则“No”;


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 110000
#define INF 0x3f3f3f3f
#define met(a, b) memset(a, b, sizeof(a))
const double EPS = 1e-8;

vector <vector <int> >G;

typedef long long LL;

int n, m, dfn[N], low[N], Time, top, flag;
int Instack[N], Stack[N];

void Init ()
{
    G.clear ();
    G.resize (n+1);

    Time = top = 0;
    memset (low, 0, sizeof (low));
    memset (dfn, 0, sizeof (dfn));
    memset (Instack, 0, sizeof (Instack));
    memset (Stack, 0, sizeof (Stack));
}

void Tarjan (int u)
{
    low[u] = dfn[u] = ++Time;
    Instack[u] = 1;
    Stack[top++] = u;
    int len = G[u].size (), v;

    for (int i=0; i<len; i++)
    {
        v = G[u][i];
        if (!dfn[v])
        {
            Tarjan (v);
            low[u] = min (low[u], low[v]);
        }
        else if (Instack[v])
        {
            flag = 1;
            low[u] = min (low[u], dfn[v]);
        }
    }

    if (low[u] == dfn[u])
    {
        do
        {
            v = Stack[--top];
            Instack[v] = 0;
        }
        while (u != v);
    }
}

int main()
{
    int t;
    scanf ("%d", &t);

    while (t--)
    {
        scanf ("%d %d", &n, &m);
        Init();

        while (m--)
        {
            int u, v;
            scanf ("%d %d", &u, &v);
            G[u].push_back(v);
        }

        for (int i=1; i<=n; i++)
        {
            flag = 0;
            if (!low[i]) Tarjan (i);
            if (flag) break;
        }

        if (flag) puts ("Yes");
        else puts ("No");
    }
    return 0;
}


你可能感兴趣的:(CQUoj 威尼斯平底渔船 (强连通))