POJ 2186 Tarjan SCC

Title

Portal POJ 2186 Popular Cows

answer

T a r j a n Tarjan T a r j a n SolveSCC SCCS C C ,DAG DAGobtained after considering the shrinking pointD A G . Nodes that meet the conditions must be inDAG DAGThe only degree of D A G is0 00 ofSCC SCCS C C , theSCC SCCof the smallest topological order from the bottom upIn S C C , construct the inverse graph to judge thisSCC SCCWhether a node in S C C can traverse all points is enough. This judgment method can be used only once from any starting pointTarjan TarjanT a r j a n . Total time complexityO (N + M) O(N+M)O ( N+M)

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10005, maxm = 50005;
int N, M, num, dfn[maxn], low[maxn];
int top, st[maxn], scc, sc[maxn];
int tot, head[maxn], to[maxm], nxt[maxm];
int tot_r, hr[maxn], tr[maxm], nr[maxm];
bool in[maxn], vs[maxn];

inline void add(int x, int y)
{
    
    
    to[++tot] = y, nxt[tot] = head[x], head[x] = tot;
    tr[++tot_r] = x, nr[tot_r] = hr[y], hr[y] = tot_r;
}

void tarjan(int x)
{
    
    
    low[x] = dfn[x] = ++num;
    st[++top] = x, in[x] = 1;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dfn[y])
            tarjan(y), low[x] = min(low[x], low[y]);
        else if (in[y])
            low[x] = min(low[x], dfn[y]);
    }
    if (low[x] == dfn[x])
    {
    
    
        ++scc;
        int y;
        do
        {
    
    
            y = st[top--], sc[y] = scc;
        } while (x != y);
    }
}

void dfs(int x)
{
    
    
    vs[x] = 1;
    for (int i = hr[x]; i; i = nr[i])
    {
    
    
        int y = tr[i];
        if (!vs[y])
            dfs(y);
    }
}

int main()
{
    
    
    scanf("%d%d", &N, &M);
    for (int i = 1, x, y; i <= M; ++i)
        scanf("%d%d", &x, &y), add(x, y);
    tarjan(1);
    int sum = 0, x = 0;
    for (int i = 1; i <= N; ++i)
        if (sc[i] == 1)
            ++sum, x = i;
    if (x)
        dfs(x);
    for (int i = 1; i <= N; ++i)
        if (!vs[i])
        {
    
    
            sum = 0;
            break;
        }
    printf("%d\n", sum);
    return 0;
}

If judge SCC SCCS C C DAG DAGafter shrinking pointDoes D A G have only one out degree of1 11 node, need to construct allSCC SCCSCC

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10005, maxm = 50005;
int N, M, num, dfn[maxn], low[maxn];
int top, st[maxn], scc, sc[maxn], deg[maxn];
int tot, head[maxn], to[maxm], nxt[maxm];
bool in[maxn], vs[maxn];

inline void add(int x, int y)
{
    
    
    to[++tot] = y, nxt[tot] = head[x], head[x] = tot;
}

void tarjan(int x)
{
    
    
    low[x] = dfn[x] = ++num;
    st[++top] = x, in[x] = 1;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dfn[y])
            tarjan(y), low[x] = min(low[x], low[y]);
        else if (in[y])
            low[x] = min(low[x], dfn[y]);
    }
    if (low[x] == dfn[x])
    {
    
    
        ++scc;
        int y;
        do
        {
    
    
            y = st[top--], sc[y] = scc;
        } while (x != y);
    }
}

int main()
{
    
    
    scanf("%d%d", &N, &M);
    for (int i = 1, x, y; i <= M; ++i)
        scanf("%d%d", &x, &y), add(x, y);
    for (int i = 1; i <= N; ++i)
        if (!dfn[i])
            tarjan(i);
    int sum = 0;
    for (int i = 1; i <= N; ++i)
        if (sc[i] == 1)
            ++sum;
    for (int i = 1; i <= N; ++i)
        for (int j = head[i]; j; j = nxt[j])
        {
    
    
            int x = sc[i], y = sc[to[j]];
            if (x != y)
                ++deg[x];
        }
    int cnt = 0;
    for (int i = 1; i <= scc; ++i)
        cnt += !deg[i];
    printf("%d\n", cnt == 1 ? sum : 0);
    return 0;
}

Guess you like

Origin blog.csdn.net/neweryyy/article/details/115016732