문제

문제 링크

어떻게 접근할 것인가?

  • 위상정렬을 활용해서 문제를 풀 수 있다.
  • 여기서 중요한 점은 포인터가 아니라 벡터만으로도 충분히 링크드 리스트를 표현할 수 있다는 것이다.

위상정렬 정리 자료

포인터로 링크드 리스트 코드

#include <string>
#include <cstdio>
#include <queue>

using namespace std;

int* in;
queue<int> q;


struct Node { 
    int data;
    Node* next, * prev; 
    Node() {
        next = prev = NULL;
        data = 0;
    }
    Node(int i, Node* ptr)//ptr 뒤에 추가
    {
        data = i;
        prev = ptr;
        next = ptr->next;
        next->prev = prev->next = this; 
    }
    void selvDelete() {
        prev->next = next;
        next->prev = prev;
        delete this;
    }
};

struct LinkedList {
    Node *head;
    Node *tail;
    int count;
    LinkedList() { //생성자
        count = 0;
        head = new Node(); //더미를 선언해서 가지고 있게한다.
        tail = new Node(); //더미를 선언해서 가지고 있게한다.
        head->next = tail; //서로연결한다.
        tail->prev = head;
    }
    void endInsert(int i) { //tail 앞에 추가한다.
        new Node(i, tail->prev);
    }
    void eraseQueue() {
        Node* tmp = head;
        while (tmp->next != NULL) {
            in[tmp->data] --;
            if(in[tmp->data] == 0) q.push(tmp->data);
            tmp = tmp->next;
        }
    }
};


int main(){
    int N, M, v1, v2;
    scanf("%d %d", &N, &M);
    LinkedList **list = new LinkedList*[N+1];
    for(int i = 0; i < N + 1; i++)list[i] = new LinkedList();
    in = new int[N+1];
    for(int i = 0; i < N + 1; i++)in[i] = 0;
    for(int i = 0 ; i < M; i++){
        scanf("%d %d", &v1, &v2);
        list[v1]->endInsert(v2);
        in[v2] ++;
    }
    for(int i = 1; i <N+1; i++){
        if(in[i] == 0) q.push(i);
    }

    while(!q.empty()){
        int temp = q.front();
        printf("%d ", temp);
        q.pop();
        list[temp]->eraseQueue();
    }
}

벡터로 링크드리스트 코드

#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

int* in;
queue<int> q;

int main(){
    int N, M, v1, v2;
    scanf("%d %d", &N, &M);
    vector<vector<int> > v;
    for(int i = 0; i < N + 1; i++)v.push_back(vector<int>());
    in = new int[N+1];
    for(int i = 0; i < N + 1; i++)in[i] = 0;
    for(int i = 0 ; i < M; i++){
        scanf("%d %d", &v1, &v2);
        v[v1].push_back(v2);
        in[v2] ++;
    }
    for(int i = 1; i <N+1; i++){
        if(in[i] == 0) q.push(i);
    }

    while(!q.empty()){
        int temp = q.front();
        printf("%d ", temp);
        q.pop();
        for(int i = 0; i < v[temp].size(); i++){
            if(--in[v[temp][i]] == 0)q.push(v[temp][i]);
        }
    }    
}

느낀점

  • 이차원 벡터이면 각 벡터가 가지고 있는 사이즈를 달리할 수 있다… 충분히 링크드 리스트 구현이 가능하다!!
  • 시간도 훨 빠르다 대박크…