정점(Vertex)과 간선(edge)로 구성된 비선형 자료구조.
e1 e2 e3 e4 1 1 1 1 0 2 1 0 0 0 3 0 1 0 1 4 0 0 1 1
출처 : visualgo.net
#include <iterator> #include <iostream> #include <vector> #include <unordered_map> using namespace std; unordered_map<int, vector<int>> adjList; vector<char> result; vector<bool> visited; void DFS(int start) { if (visited[start]) return; result.push_back(start + 'A'); visited[start] = true; for (auto& adjNode : adjList[start]) { DFS(adjNode); } } vector<char> solution(vector<pair<char, char>> graph, char start) { visited.resize(26,false); result = vector<char>(0); for (auto& [from, to] : graph) { adjList[from-'A'].push_back(to-'A'); } DFS(start-'A'); return result; } void init() { adjList.clear(); result.clear(); visited.clear(); } void print(vector<char> vec) { copy(vec.begin(), vec.end(), std::ostream_iterator<char>(cout, " ")); cout << endl; } int main() { //bool 반환할 때 true는 1, false는 0 입니다. print(solution({{'A', 'B'}, {'B', 'C'}, {'C', 'D'}, {'D', 'E'}}, 'A')); //출력값 : A B C D E init(); print(solution({{'A', 'B'}, {'A', 'C'}, {'B', 'D'}, {'B', 'E'}, {'C', 'F'}, {'E', 'F'}}, 'A')); //출력값 : A B D E F C return 0; }
출처 : visualgo.net
//아래 코드는 테스트 코드 입니다. #include <iterator> #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <queue> using namespace std; unordered_map<int, vector<int>> adjList; vector<int> result; unordered_set<int> visited; void BFS(int start) { queue<int> q; q.push(start); visited.insert(start); result.push_back(start); while(!q.empty()) { int front = q.front(); q.pop(); for (auto& adj : adjList[front]) { if (visited.find(adj) == visited.end()) { visited.insert(adj); result.push_back(adj); q.push(adj); } } } } vector<int> solution(vector<pair<int,int>> graph, int start) { for (auto& [from, to] : graph) { adjList[from].push_back(to); } BFS(start); return result; } void init() { adjList.clear(); result.clear(); visited.clear(); } void print(vector<int> vec) { copy(vec.begin(), vec.end(), std::ostream_iterator<int>(cout, " ")); cout << endl; } int main() { print(solution({{1, 2}, {1, 3}, {2, 4}, {2, 5}, {3, 6}, {3, 7}, {4, 8}, {5, 8}, {6, 9}, {7, 9}}, 1)); //출력값 : 1 2 3 4 5 6 7 8 9 init(); print(solution({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 0}}, 1)); //출력값 : 1 2 3 4 5 0 return 0; }
DFS와 BFS의 visited 처리 순서에 주의
출처 : visualgo.net
#include <iterator> #include <iostream> #include <vector> #include <unordered_map> #include <queue> #include <climits> using namespace std; unordered_map<int, vector<pair<int, int>>> graph; vector<vector<int>> dijkstraVec; void Dijkstra(int start, int numNodes) { dijkstraVec.clear(); //[0] 시작점에서 i까지의 거리 //[1] i의 직전 노드 dijkstraVec.resize(numNodes, vector<int>(2, INT_MAX)); //최소비용 dijkstraVec[start][0] = 0; //직전 노드 dijkstraVec[start][1] = 0; vector<bool> visited(numNodes,false); auto cmp = [](const pair<int,int>& a, const pair<int,int>& b){ return a.first > b.first; }; // dist, 노드번호 priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(cmp)> unVisited(cmp); unVisited.push({0, start}); // 거리 정보가 갱신된 노드만 q에 넣음 // 연결 그래프라면 모든 노드를 탐방 while(!unVisited.empty()) { auto& [dist, u] = unVisited.top(); unVisited.pop(); if (visited[u]) continue; visited[u] = true; for (auto& [v, weight] : graph[u]) { if (visited[v]) continue; if (dijkstraVec[v][0] > dist + weight) { dijkstraVec[v][0] = dist + weight; dijkstraVec[v][1] = u; unVisited.push({dijkstraVec[v][0], v}); } } } } vector<int> solution(int start, int numNodes, vector<tuple<int, int, int>> edges) { vector<int> answer; graph.clear(); for (auto& [from, to, weight] : edges) { graph[from].push_back({to, weight}); } Dijkstra(start, numNodes); for (auto& v : dijkstraVec) { answer.push_back(v[0]); } return answer; } void print(vector<int> vec) { copy(vec.begin(), vec.end(), std::ostream_iterator<int>(cout, " ")); cout << endl; } int main() { print(solution(0, 3, {{0, 1, 9},{0, 2, 3},{1, 0, 5},{2, 1, 1}})); //출력값 : 0 4 3 print(solution(0, 4, {{0, 1, 1}, {1, 2, 5}, {2, 3, 1}})); //출력값 : 0 1 6 7 return 0; }
출처 : visualgo.net
#include <iterator> #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <climits> #include <algorithm> using namespace std; unordered_set<int> allvertices; unordered_map<int, vector<pair<int,int>>> graph; // <minVAl,u> unordered_map<int, pair<int,int>> distAndUList; bool BellmanFord(int source) { for(auto& vertex : allvertices) { distAndUList[vertex] = make_pair(INT_MAX, INT_MAX); } distAndUList[source] = {0,0}; for (int i=0; i<allvertices.size()-1; i++) { // k = 거쳐갈 노드 for (auto& k : allvertices) { if (distAndUList[k].first == INT_MAX) continue; //u->k->v 와 비교해서 값 갱신 for (auto& [v, weight] : graph[k]) { if (distAndUList[v].first > distAndUList[k].first + weight) { distAndUList[v].first = distAndUList[k].first + weight; distAndUList[v].second = k; } } } } // k = 거쳐갈 노드 for (auto& k : allvertices) { //u->k->v 와 비교해서 값 갱신 for (auto& [v, weight] : graph[k]) { if (distAndUList[k].first == INT_MAX) continue; //u->k->v 와 비교해서 값 갱신 if (distAndUList[v].first > distAndUList[k].first + weight) { return false; } } } return true; } vector<int> solution(int num_vertices, vector<tuple<int, int, int>> edges, int source) { vector<int> answer; // 간선을 정보를 통해서 그래프의 구조 파악 for(auto& [from, to, weight] : edges) { allvertices.insert(from); allvertices.insert(to); graph[from].push_back({to, weight}); } bool belowZeroCycle = !BellmanFord(source); vector<pair<int, int>> sortedDist; for (auto& [v, data] : distAndUList) { sortedDist.push_back({v, data.first}); // v: 정점 번호, data.first: 거리 } sort(sortedDist.begin(), sortedDist.end()); // v 기준 정렬 if (!belowZeroCycle) { for (auto& [u , dist] : sortedDist) { answer.push_back(dist); } } else { answer.push_back(-1); } return answer; } void print(vector<int> vec) { copy(vec.begin(), vec.end(), std::ostream_iterator<int>(cout, " ")); cout << endl; } int main() { print(solution(5, {{0, 1, 4}, {0, 2, 3}, {0, 4, -6}, {1, 3, 5}, {2, 1, 2}, {3, 0, 7}, {3, 2, 4},{4, 2, 2}}, 0)); //출력값 : 0 -2 -4 3 -6 print(solution(4, {{0, 1, 5}, {0, 2, -1}, {1, 2, 2}, {2, 3,-2}, {3, 0, 2}, {3, 1, 6}}, 0)); //출력값 : -1 return 0; }
//아래 코드는 테스트 코드 입니다. #include <iterator> #include <iostream> #include <vector> #include <unordered_map> #include <unordered_set> #include <climits> #include <algorithm> using namespace std; unordered_set<int> allvertices; unordered_map<int, vector<pair<int,int>>> graph; vector<vector<int>> distanceMatrix; int n = 0; void FW() { distanceMatrix.resize(n, vector<int>(n,INT_MAX)); for (int i=0; i<n; i++) { distanceMatrix[i][i] = 0; } for(auto& [from, data] : graph) { for (auto& [to, weight] : data) { distanceMatrix[from][to] = weight; } } for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j=0; j < n; j++) { if (distanceMatrix[i][k] != INT_MAX && distanceMatrix[k][j] != INT_MAX) { distanceMatrix[i][j] = min(distanceMatrix[i][j], distanceMatrix[i][k] + distanceMatrix[k][j]); } } } } } vector<int> solution(vector<tuple<int, int, int>> edges) { graph.clear(); allvertices.clear(); distanceMatrix.clear(); n = 0; vector<int> answer; // 간선을 정보를 통해서 그래프의 구조 파악 for(auto& [from, to, weight] : edges) { if(allvertices.insert(from).second) n++; if(allvertices.insert(to).second) n++; graph[from].push_back({to, weight}); } FW(); for (int i = 0; i < n; i++) { // 음수 사이클 존재 if (distanceMatrix[i][i] < 0) { answer.push_back(-1); return answer; } } vector<int> temp(allvertices.begin(), allvertices.end()); sort(temp.begin(), temp.end()); // 값을 확인하기 위한 출력코드 int source = 0; for (int v : temp) { answer.push_back(distanceMatrix[source][v] == INT_MAX ? -1 : distanceMatrix[source][v]); } return answer; } void print(vector<int> vec) { copy(vec.begin(), vec.end(), std::ostream_iterator<int>(cout, " ")); cout << endl; } int main() { print(solution({{0, 1, 4}, {0, 2, 3}, {0, 4, -6}, {1, 3, 5}, {2, 1, 2}, {3, 0, 7}, {3, 2, 4},{4, 2, 2}})); //출력값 : 0 -2 -4 3 -6 print(solution({{0, 1, 5}, {0, 2, -1}, {1, 2, 2}, {2, 3,-2}, {3, 0, 2}, {3, 1, 6}})); //출력값 : -1 return 0; }