본문 바로가기
배움의공간(學)/알고리즘

[그래프] 사이클 찾기

by ㅋㅕㅋㅕㅇㅣ 2021. 2. 5.

1. 사이클을 이루는 정점 확인

1) BFS

bool findCycle(int here, int depth) {
	stack<int> s;

	// 사이클을 만나면 while문 종료
	while (visit[here] == 0) {
		s.push(here);
		visit[here] = depth++;		
		here = node[here];
	}

	// cnt: 사이클 크기
	int cnt = depth - visit[here];	
	cycle[here] = true; 

	// 사이클에 포함되는 정점들을 마킹
	while (cnt > 0) {
		int item = s.top();
		s.pop();
		cycle[item] = true;
		cnt--;
	}

	return cycle[here];
}

2) DFS

int cnt;

bool findCycleDfs(int here, int depth) {
        visit[here] = depth;
        int next = node[here];
        
        if (visited[next] > 0) {
            cnt = depth - visit[next];
            cycle[next] = true;            
            return cycle[next];
        }                
        
        if (findCycleDfs(next, depth + 1) && cnt > 0) {
            cycle[next] = true;
            cnt--;
        }
        
        return cycle[next];
    }

 

2. 사이클 존재 여부만 확인

1) 최소신장트리(MST)

  - findParent 으로 부모가 동일하지 않은 정점만 연결 (이것을 카운팅)

  - 모든 정점을 방문하지 못하는 경우, 간선의 개수가 N-1 이 아니다.

  - 크루스칼 알고리즘, union-find 이용

int kruskal()
{
    // 간선의 비용을 기준으로 오름차순 정렬
    sort(v.begin(), v.end());
 
    int sum = 0;
    int selected = 0;
 
    for (int i = 1; i < v.size(); i++) {
        // 사이클이 발생하지 않는 경우 그래프에 포함
        if (!findParent(v[i].from, v[i].to)) {
            sum += v[i].dist;
            selected++;
            unionParent(v[i].from, v[i].to);
        }
    }
 
    // 간선의 수 != (정점의 수 - 1)인 경우, 연결 불가능한 정점이 있음
    return selected == (n - 1) ? sum : -1;
}

 

2) 위상정렬 이용

  - 모든 노드를 방문하기 전에 큐가 빈다면, 사이클이 존재한다고 판단

  - BFS + indegree 개수

void topologySort()
{
    // indegree = 0 인 노드를 큐에 삽입
    for (int i = 1; i <= N; i++) {
        visited[i] = 0;
        if (indegree[i] == 0) {
            q.push(i);
        }
    }
 
    // 큐가 빌 때까지 수행
    while (!q.empty()) {
        int x = q.front();
        q.pop();
 
        for (Edge y : adj[x]) {
            // 큰 값 채택 : 다음번 노드에 이미 저장된 비용 vs 현재 큐 진행시 비용(current + next.cost)
            result[y.node] = max(result[y.node], result[x] + y.cost);
            if (--indegree[y.node] == 0) {
                q.push(y.node);
            }
        }
    }
}

'배움의공간(學) > 알고리즘' 카테고리의 다른 글

[백준] 2252-줄 세우기  (0) 2021.04.05
[기출] 디자이너의 고민  (0) 2021.02.10
[기출] 산책하자  (0) 2020.12.18
기본 알고리즘  (0) 2020.12.14
알고리즘 학습  (0) 2020.10.20

댓글