POJ 1904 King's Quest

强连通分量

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;


const int maxn=5000;
vector<int>G[maxn];
vector<int>FG[maxn];
vector<int>Edge[maxn];
int flag[maxn],dfn[maxn],Belong[maxn];
int N,t,to,Time,Block;
struct Point
{
    int id, dfn;
} point[maxn];


bool cmp(const Point&a, const Point&b)
{
    return a.dfn>b.dfn;
}

void init()
{
    for(int i=0; i<maxn; i++) G[i].clear();
    for(int i=0; i<maxn; i++) FG[i].clear();
    for(int i=0; i<maxn; i++) Edge[i].clear();

    memset(flag,0,sizeof(flag));
    memset(dfn,0,sizeof(dfn));
    memset(Belong,0,sizeof(Belong));
    Time=0,Block=0;
}

void dfs(int now)
{
    flag[now]=1;
    for(int i=0; i<G[now].size(); i++)
        if(!flag[G[now][i]])
            dfs(G[now][i]);
    Time++;
    dfn[now]=Time;
}

void Dfs(int now)
{
    Belong[now] = Block;
    for (int i = 0; i<FG[now].size(); i++)
        if (!Belong[FG[now][i]])
            Dfs(FG[now][i]);
}

int main()
{
    while(~scanf("%d",&N))
    {
        init();
        for(int i=1; i<=N; i++)
        {
            scanf("%d",&t);
            while(t--)
            {
                scanf("%d",&to);
                G[i].push_back(to+N);
                FG[to+N].push_back(i);
                Edge[i].push_back(to);
            }
        }
        for(int i=1; i<=N; i++)
        {
            scanf("%d",&t);
            G[t+N].push_back(i);
            FG[i].push_back(t+N);
        }
        for (int i=1; i<=2*N; i++) if(!dfn[i]) dfs(i);
        for (int i=0; i<2*N; i++) point[i].id =i+1,point[i].dfn=dfn[i+1];
        sort(point, point + N, cmp);
        for (int i = 0; i<2*N; i++)
            if (!Belong[point[i].id])
                Block++, Dfs(point[i].id);
        int TOT;
        int Cun[maxn];
        for(int i=1; i<=N; i++)
        {
            TOT=0;
            sort(Edge[i].begin(),Edge[i].end());
            for(int j=0; j<Edge[i].size(); j++)
            {
                if(Belong[i]==Belong[Edge[i][j]+N])
                {
                    Cun[TOT]=Edge[i][j];
                    TOT++;
                }
            }
            printf("%d",TOT);
            for(int x=0; x<TOT; x++) printf(" %d",Cun[x]);
            printf("\n");
        }
    }
    return 0;
}

 

posted @ 2015-09-01 11:16  Fighting_Heart  阅读(155)  评论(0编辑  收藏  举报