COJ 1128 Download Station

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1128

这道题是裸的强连通分量,之前没有写类似的题,所以敲的很辛苦。

/*Accepted    920 KB    32 ms    C++    2240 B    2012-07-28 16:54:39*/

#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

using namespace std;



const int MAXN = 1 << 7;

struct edge

{

    int v, n;

} e[MAXN *MAXN];



int first[MAXN], es;



void addedge(int u, int v)

{

    e[es].v = v, e[es].n = first[u], first[u] = es++;

}



int n, m, tu, tv, ans;

int dfn[MAXN], low[MAXN], col[MAXN], stk[MAXN], ins[MAXN], ind, top, cols, tmp;

int indg[MAXN], outdg[MAXN], zeroin, zeroout;



void dfs(int u)

{

    dfn[u] = low[u] = ++ind;

    stk[++top] = u, ins[u] = 1;

    for(int i = first[u]; i != -1; i = e[i].n)

    {

        int v = e[i].v;

        if( dfn[v] == 0)

        {

            dfs(v);

            if(low[v] < low[u]) low[u] = low[v];

        }

        else if(ins[v])

        {

            if(dfn[v] < low[u]) low[u] = dfn[v];

        }

    }

    if(dfn[u] == low[u])

    {

        cols++;

        do

        {

            tmp = stk[top--];

            col[tmp] = cols;

            ins[tmp] = 0;

        }while(tmp != u);

    }

}





void tarjan( int n)

{

    memset(dfn, 0, sizeof dfn);

    memset(low, 0, sizeof low);

    memset(col, 0, sizeof col);

    memset(stk, 0, sizeof stk);

    memset(ins, 0, sizeof ins);

    ind = top = cols = 0;

    for(int i = 1; i <= n; i++)

    {

        if( dfn[i] == 0) dfs(i);

    }

    if(cols == 1)

    {

        ans = 0;

        return;

    }

    ans = zeroin = zeroout = 0;

    memset(indg, 0, sizeof indg);

    memset(outdg, 0, sizeof outdg);

    for(int u = 1; u <= n; u++)

    {

        for(int i = first[u]; i != -1; i = e[i].n)

        {

            int v = e[i].v;

            if(col[u] == col[v])continue;

            indg[col[v]]++;

            outdg[col[u]]++;

        }

    }

    for(int i = 1; i <= cols; i++)

    {

        if(indg[i] == 0)zeroin++;

        if(outdg[i] == 0)zeroout++;

    }

    ans = zeroin > zeroout ? zeroin : zeroout;

}



int main()

{

    while( scanf( "%d", &n) != EOF)

    {

        memset( first, -1, sizeof first);

        for( int i = 1; i <= n; i ++)

        {

            int a;

            while( true)

            {

                scanf( "%d", &a);

                if( a == 0) break;

                addedge( i, a);

            }

        }

        tarjan(n);

        printf( "%d\n", ans);

    }

    return 0;

}

 

 

你可能感兴趣的:(download)