jongman book으로 공부하고 있는학생입니다.

  • shinhj88
    shinhj88

    Strongly Connected Component

    강결합 컴포넌트 알고리즘을 jongman책 대로 작성하였는데 오답이 뜨는데 무슨이 유때문이지 모르겠습니다.

    introduction to algorithms 에서 배운대로 DFS를 한번 돌린후 finish타임의 역순으로 다시 DFS 역방향 간선을 이용하여 문제를 풀었을땐 답이나오는데 제가 어떤 부분을 잘못하였는지 찾지못해서 도움을 요청합니다. 도와주세요~~

    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <set>
    #include <algorithm>
    using namespace std;
    #define MAX_N 10001
    vector<int> adj[MAX_N];
    int N;
    vector<int> discover,finish;
    vector<set<int> > scc;
    int time;
    stack<int> Scc_V;
    int SccCount;
    void input()
    {
        int M;
        scc.clear();
        scanf("%d%d",&N,&M);
        for(int i=0;i<M;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            adj[a].push_back(b);
        }
    
    }
    int Scc(int here)
    {
        int ret=discover[here]=time++;
        Scc_V.push(here);
        for(int i=0;i<adj[here].size();i++)
        {
            int there=adj[here][i];
            if(discover[there]==-1)ret=min(ret,Scc(there));
            else if(discover[there]<discover[here]&&finish[there]!=1)ret=min(ret,discover[there]);
        }
        if(ret==discover[here])
        {
            scc.push_back(set<int>());
            while(true)
            {
                int t=Scc_V.top();
                Scc_V.pop();
                scc[scc.size()-1].insert(t);
                if(t==here)break;
            }      
        }
        finish[here]=1;
        return ret;
    
    }
    int cmp(const set<int>& a,const set<int>&b)
    {
        return (*a.begin())<(*b.begin());
    }
    void tarjanScc()
    {
        discover=finish=vector<int>(N+1,-1);
        time=0;
        SccCount=0;
        for(int i=1;i<=N;i++)
        {
            if(discover[i]==-1)Scc(i);
        }
        sort(scc.begin(),scc.end(),cmp);
    }
    void output()
    {
        set<int>::iterator ite;
        printf("%d\n",scc.size());
        for(int i=0;i<scc.size();i++)
        {
            for(ite=scc[i].begin();ite!=scc[i].end();ite++)printf("%d ",(*ite));
            printf("-1\n");
    
        }
    }
    int main()
    {
        input();
        tarjanScc();
        output();
        return 0;
    }
    

    이것은 정답이 나왔던 코드입니다.

    #include <cstdio>
    #include <vector>
    #include <memory.h>
    #include <algorithm>
    using namespace std;
    vector<int> G[10001],GT[10001];
    vector<int> stack;
    vector<int> ans;
    int V,E;
    bool check[10001];
    void input()
    {
        scanf("%d %d",&V,&E);
        stack.reserve(V);
        for(int i=0;i<E;i++)
        {
            int a,b;
            scanf("%d %d",&a,&b);
            G[a].push_back(b);
            GT[b].push_back(a);
        }
    }
    int cmp(const vector<int> a,const vector<int> b)
    {
        return a[0]<b[0];
    }
    void DFS(int v,const vector<int> *vertex,bool T)
    {
        check[v]=true;
        for(int i=0;i<vertex[v].size();i++)
        {
            if(check[vertex[v][i]]==false)
            {
                if(T)ans.push_back(vertex[v][i]);
                DFS(vertex[v][i],vertex,T);
            }
        }
        if(!T)stack.push_back(v);
    }
    int main()
    {
        input();
        for(int i=1;i<=V;i++)
        {
            if(check[i]==false)
            {
                DFS(i,G,false);
            }
        }
        memset(check,false,sizeof(check));
        vector<vector<int> > print;
        ans.reserve(V);
        while(!stack.empty())
        {
            if(check[stack.back()]==false)
            {
                ans.push_back(stack.back());
                DFS(stack.back(),GT,true);
                sort(ans.begin(),ans.end());
                print.push_back(ans);
                ans.clear();
            }
            stack.pop_back();
    
        }
        sort(print.begin(),print.end(),cmp);
        printf("%d\n",print.size());
        for(int i=0;i<print.size();i++)
        {
            for(int j=0;j<print[i].size();j++)
            {
                printf("%d ",print[i][j]);
            }
            printf("-1\n");
        }
    
        return 0;
    }
    

    10년 전
2개의 댓글이 있습니다.
  • sven
    sven

    책에 오류가 있었다는 것 같습니다.
    http://book.algospot.com/tarjan.html


    10년 전 link
  • JongMan
    JongMan

    아.... 제가 이 글을 잘 봤으면 3쇄에 고쳤었을 수도 있는 오류인데.... ㅠ.ㅠ


    10년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.