ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 오일러 서킷을 찾아내는 알고리즘
    알고리즘 이론/알고리즘 구현 2019. 8. 28. 02:47

    오일러 서킷이란?


    깊이 우선 탐색을 이용해 풀 수 있는 유명한 문제로, 그래프의 모든 간성르 정확히 한 번씩 지나서 시작점으로 돌아오는 경로를 찾는 문제이다.


    모든 정점이 짝수점이면서, 간선들이 하나의 컴포넌트에 포함된 그래프가 주어진다면 항상 오일러 서킷을 찾아내는 알고리즘을 만들 수 있다.


    findRandomCircuit(u)는 u와 인접한 간선들을 하나하나 검사하면서, 아직 방문하지 않은 간선 (u,v)가 있다면 또다시 findRandomCircuit(v)를 호출. 더이상 


    따라갈 간선이 없다면 재귀 호출 종료후 반환한다.


    재귀 호출이 끝나고 반환할 때 경로에 추가해줌 으로서 경로의 끝점부터 역순으로 간선들이 추가된다.




    코드 ( C+ + )


    #include <iostream>

    #include <vector>

    using namespace std;

    // 그래프의 인접 행렬 표현, adj[i][j] = i 와 j 사이의 간선의 수

    vector<vector<int>> adj;


    // 무향 그래프의 인접 행렬 adj가 주어질 때 오일러 서킷을 계산한다.

    // 결과로 얻어지는 circuit을 뒤집으면 오일러 서킷이 된다.

    void getEulerCircuit(int here, vector<int>& circuit)

    {

    for (int i = 0; i < adj.size(); ++i)

    {

    if (adj[here][i] > 0) {

    adj[here][i]--; // 양쪽 간선을 모두 지운다.

    adj[i][here]--;

    getEulerCircuit(i, circuit);

    }

    }

    circuit.push_back(here);

    }


    int main()

    {

    int n = 6;

    adj = vector<vector<int>>(n, vector<int>(n, 0));

    adj[0][1] = 1;

    adj[1][2] = 1;

    adj[2][4] = 1;

    adj[2][3] = 1;

    adj[4][5] = 1;

    adj[5][2] = 1;

    adj[3][0] = 1;


    vector<int> circuit;

    getEulerCircuit(0, circuit);



    cout << "뒤집기 전 " << endl;

    for (int i = 0; i < circuit.size(); ++i)

    cout << circuit[i] << " ";


    reverse(circuit.begin(), circuit.end());

    cout << endl;



    cout << "뒤집기 후 " << endl;

    for (int i = 0; i < circuit.size(); ++i)

    cout << circuit[i] << " ";


    return 0;

    }




    참고 문헌 : 알고리즘 해결 전략


Designed by Tistory.