[C++] κ°•ν•œ μ—°κ²° μš”μ†Œ(νƒ€μž”, 코사라주)

2021. 6. 27. 18:35Β·πŸ“ Computer Science/✏ Algorithm

κ°•ν•œ μ—°κ²° μš”μ†Œ(Strongly Connected Component)

  • 두 정점에 λŒ€ν•΄ μ–‘λ°©ν–₯으둜 이동 κ°€λŠ₯ν•œ κ²½λ‘œκ°€ λͺ¨λ‘ μžˆμ„ λ•Œ 두 정점은 같은 κ°• κ²°ν•© μ»΄ν¬λ„ŒνŠΈ(SCC)에 μ†ν•œλ‹€. μ¦‰, κ·Έλž˜ν”„μ˜ μ‚¬μ΄ν΄μ—μ„œ 같은 사이클 내에 μ‘΄μž¬ν•˜λŠ” 정점듀은 같은 SCC에 μ†ν•œλ‹€κ³  ν•  수 μžˆλ‹€.
  • λ°©ν–₯ κ·Έλž˜ν”„μ—μ„œλ§Œ μ •μ˜λœλ‹€.

 

1. νƒ€μž” μ•Œκ³ λ¦¬μ¦˜

1) κΈ°λ³Έ 원리

  • 깊이 μš°μ„  탐색
  • λ°©ν–₯ κ·Έλž˜ν”„μ˜ 정점듀을 λ°©λ¬Έν•œ ν›„ λ°©λ¬Έν•œ μ •μ μ˜ 간선을 톡해 μƒμœ„μ—μ„œ 방문된 정점을 λ°©λ¬Έν•œλ‹€λ©΄ SCCκ°€ μ‘΄μž¬ν•œλ‹€κ³  νŒλ‹¨ν•œλ‹€.

Tarjan algorithm

 

2) 문제

 

https://www.acmicpc.net/problem/2150

 

2150번: Strongly Connected Component

첫째 쀄에 두 μ •μˆ˜ V(1 ≤ V ≤ 10,000), E(1 ≤ E ≤ 100,000)κ°€ μ£Όμ–΄μ§„λ‹€. μ΄λŠ” κ·Έλž˜ν”„κ°€ V개의 정점과 E개의 κ°„μ„ μœΌλ‘œ 이루어져 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ‹€μŒ E개의 μ€„μ—λŠ” 간선에 λŒ€ν•œ 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •

www.acmicpc.net

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

vector<int> graph[10001];

vector<vector<int>> groups;
stack<int> group; // λ°©λ¬Έν•œ λ…Έλ“œλ“€
bool grouped[10001]; // κ·Έλ£Ήν•‘
int check[10001]; // λ°©λ¬Έ μˆœμ„œ
int num = 0; // λ°©λ¬Έ μˆœμ„œ 인덱슀

int dfs(int index)
{
    check[index] = ++num;
    group.push(index);

    int parent = check[index];
    for (int i = 0; i < graph[index].size(); i++) {
        int child = graph[index][i];

        if (!check[child])
            parent = min(parent, dfs(child));
        else if (!grouped[child])
            parent = min(parent, check[child]);
    }

    if (parent == check[index])
    {
        vector<int> v;
        while (true) {
            int t = group.top();
            group.pop();

            grouped[t] = true;
            v.push_back(t);

            if (t == index)
                break;
        }

        sort(v.begin(), v.end());
        groups.push_back(v);
    }

    return parent;
}

int main()
{
    int V, E;
    cin >> V >> E;

    for (int i = 0; i < E; i++) {
        int a, b;
        cin >> a >> b;
        graph[a].push_back(b);
    }

    for (int i = 1; i <= V; i++)
        if (!check[i])
            dfs(i);

    sort(groups.begin(), groups.end());

    cout << groups.size() << '\n';
    for (int i = 0; i < groups.size(); i++) {
        for (int j = 0; j < groups[i].size(); j++)
            cout << groups[i][j] << ' ';
        cout << "-1\n";
    }
}

 

2. 코사라주 μ•Œκ³ λ¦¬μ¦˜

1) κΈ°λ³Έ 원리

  • 깊이 μš°μ„  탐색
  • 탐색이 μ’…λ£Œλ˜λŠ” μˆœμ„œλŒ€λ‘œ 정점을 μŠ€νƒμ— μ €μž₯ν•˜κ³  μŠ€νƒμ˜ 상단뢀터 μ—­λ°©ν–₯ κ·Έλž˜ν”„λ₯Ό 타고 DFS을 μˆ˜ν–‰ν•œλ‹€.

 

2) 문제

 

https://www.acmicpc.net/problem/2150

 

2150번: Strongly Connected Component

첫째 쀄에 두 μ •μˆ˜ V(1 ≤ V ≤ 10,000), E(1 ≤ E ≤ 100,000)κ°€ μ£Όμ–΄μ§„λ‹€. μ΄λŠ” κ·Έλž˜ν”„κ°€ V개의 정점과 E개의 κ°„μ„ μœΌλ‘œ 이루어져 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ‹€μŒ E개의 μ€„μ—λŠ” 간선에 λŒ€ν•œ 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •

www.acmicpc.net

#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;

vector<int> graph[10001], rev_graph[10001];

vector<vector<int>> groups(10001);
stack<int> nodes;
bool check[10001];
int groupsCount = 0;

void dfs(int index)
{
	if (check[index])
		return;

	check[index] = true;
	for (int i = 0; i < graph[index].size(); i++)
		dfs(graph[index][i]);

	nodes.push(index); // 탐색이 μ’…λ£Œλ˜λ©΄ 정점 μ €μž₯
}

void rev_dfs(int index)
{
	if (check[index])
		return;

	check[index] = true;
	groups[groupsCount].push_back(index);
	for (int i = 0; i < rev_graph[index].size(); i++)
		rev_dfs(rev_graph[index][i]);
}

int main()
{
	int V, E;
	cin >> V >> E;
	for (int i = 0; i < E; i++) {
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
		rev_graph[b].push_back(a);
	}

	for (int i = 1; i <= V; i++)
		if (!check[i])
			dfs(i);

	memset(check, false, sizeof(check));
	while (!nodes.empty()) {
		if (!check[nodes.top()]) {
			rev_dfs(nodes.top());

			sort(groups[groupsCount].begin(), groups[groupsCount].end());
			groupsCount++;
		}

		nodes.pop();
	}

	sort(groups.begin(), groups.begin() + groupsCount);

	cout << groupsCount << '\n';
	for (int i = 0; i < groupsCount; i++) {
		for (int j = 0; j < groups[i].size(); j++)
			cout << groups[i][j] << ' ';
		cout << "-1\n";
	}
}
μ €μž‘μžν‘œμ‹œ (μƒˆμ°½μ—΄λ¦Ό)
'πŸ“ Computer Science/✏ Algorithm' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • [C++] νŽœμœ… 트리(Fenwick Tree)
  • [C++] μŠ€μœ„ν•‘ μ•Œκ³ λ¦¬μ¦˜(Sweeping Algorithm)
  • [C++] μ΅œμ†Œ μ‹ μž₯ 트리(크루슀칼)
  • [C++] μ„Έκ·Έλ¨ΌνŠΈ 트리(Segment Tree)
Blxxming
Blxxming
CS 지식과 κ³΅λΆ€ν•˜λ‹€ 배운 것, κ²½ν—˜ν•œ 것 등을 κΈ°λ‘ν•˜λŠ” λΈ”λ‘œκ·Έμž…λ‹ˆλ‹€.
  • Blxxming
    πŸ’‘λ²ˆλœ©πŸ’‘
    Blxxming
  • 전체
    였늘
    μ–΄μ œ
  • 곡지사항

    • Tech Interview
    • πŸ“š Tech (246)
      • πŸ“ Computer Science (96)
        • ✏ OS (12)
        • ✏ Network & Web (10)
        • ✏ Database (11)
        • ✏ Data Structure (6)
        • ✏ Algorithm (40)
        • ✏ Design Pattern (9)
        • ✏ Cloud Computing (3)
        • ✏ (5)
      • πŸ“ Language (73)
        • ✏ Language (6)
        • ✏ C & C++ (11)
        • ✏ C# (19)
        • ✏ JAVA (37)
      • πŸ“ Game (43)
        • ✏ Computer Graphics (2)
        • ✏ Unity (14)
        • ✏ Unreal (26)
        • ✏ (1)
      • πŸ“ Book (34)
        • ✏ Effective (3)
        • ✏ Game Server (16)
        • ✏ Clean Code (14)
        • ✏ (1)
  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.0
Blxxming
[C++] κ°•ν•œ μ—°κ²° μš”μ†Œ(νƒ€μž”, 코사라주)
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”