ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 - 9466 [C++]
    문제 풀이/백준 2023. 7. 18. 23:16
    반응형

     이 문제는 강한 연결 요소 (SCC) 를 이용해서 풀 수 있는 문제이다. 사실 이 문제는 dfs 를 약간만 설정해서 사이클의 판단만 해주면 풀리는 문제이다. 그러나 강한 연결 요소를 통해 유향 그래프의 사이클 요소를 찾을 수 있다는 생각이 떠올라 SCC로 풀었다.

     이 문제에서 중요한 건 입력으로 주어지는 간선은 outgoing edge가 단 하나라고 명시되어 있지만, transpose graph 에서는 outgoing edge 가 하나가 아니라는 것이다. 그 사실을 망각하고 풀어서 많은 시간을 쏟게 되었다.

     

     

     

    #include <vector>
    #include <stack>
    #include <iostream>
    using namespace std;
    
    vector<int> edges;
    vector<vector<int>> transEdges;
    vector<bool> visited;
    vector<int> tempScc;
    vector<vector<int>> scc;
    stack<int> st;
    
    void dfs(int start)
    {
    	int next;
    
    	visited[start] = true;
    	next = edges[start];
    
    	if (!visited[next])
    	{
    		dfs(next);
    	}
    
    	st.push(start);
    }
    
    void transDfs(int start)
    {
    	int next;
    
    	visited[start] = true;
    	for (int i = 0; i < transEdges[start].size(); i++)
    	{
    		int next = transEdges[start][i];
    
    		if (!visited[next])
    		{
    			transDfs(next);
    		}
    	}
    
    	tempScc.push_back(start);
    }
    
    int main()
    {
    	ios_base::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    
    	int test_case;
    
    	cin >> test_case;
    
    	for (int test = 0; test < test_case; test++)
    	{
    		int n, answer;
    
    		cin >> n;
    
    		answer = n;
    		visited = vector<bool>(n + 1, false);
    		edges = vector<int>(n + 1, -1);
    		transEdges = vector<vector<int>>(n + 1, vector<int>());
    		st = stack<int>();
    
    		for (int i = 1; i <= n; i++)
    		{
    			int temp;
    
    			cin >> temp;
    
    			edges[i] = temp;
    			transEdges[temp].push_back(i);
    		}
    
    		for (int i = 1; i <= n; i++)
    		{
    			if (!visited[i])
    			{
    				dfs(i);
    			}
    		}
    
    		visited = vector<bool>(n + 1, false);
    
    		while (!st.empty())
    		{
    			int present = st.top();
    			st.pop();
    
    			if (!visited[present])
    			{
    				tempScc.clear();
    				transDfs(present);
    				scc.push_back(tempScc);
    			}
    		}
    
    		for (int i = 0; i < scc.size(); i++)
    		{
    			if (scc[i].size() >= 2)
    			{
    				answer -= scc[i].size();
    			}
    			else if (scc[i].size() == 1)
    			{
    				int temp = scc[i].front();
    
    				if (edges[temp] == temp)
    				{
    					answer--;
    				}
    			}
    		}
    
    		cout << answer << '\n';
    
    		scc.clear();
    	}
    }
    반응형

    '문제 풀이 > 백준' 카테고리의 다른 글

    백준 - 20056 [C++]  (0) 2023.07.18
    백준 - 12851 [C++]  (0) 2023.07.18
    백준 - 2146 [C++]  (0) 2023.07.18
    백준 - 9019 [C++]  (0) 2023.07.18
    백준 - 게리맨더링 2 (17779) [C++]  (0) 2023.03.27
Designed by Tistory.