-
[Python][C++] 1238번 파티Algorithm/Baekjoon 2024. 10. 2. 16:31
문제
https://www.acmicpc.net/problem/1238
코드
1. Python
import sys import heapq input = sys.stdin.readline # 빠른 입력을 위해 sys.stdin.readline 사용 # n: 마을의 개수, m: 도로의 개수, x: 파티가 열리는 마을 번호 n, m, x = map(int, input().split()) # 그래프 초기화 (1번 마을부터 시작하므로 n+1 크기) graph = [[] for _ in range(n + 1)] # m개의 도로 입력 처리 for _ in range(m): start, end, w = map(int, input().split()) # start: 출발 마을, end: 도착 마을, w: 도로의 거리 graph[start].append([end, w]) # 출발 마을에서 도착 마을로 가는 도로와 그 거리를 저장 # 다익스트라 알고리즘 구현 def dijkstra(v): # 각 마을까지의 최소 거리를 기록할 리스트, 초기에는 매우 큰 값으로 설정 visited = [1e9] * (n + 1) visited[v] = 0 # 시작 마을에서 시작 마을로 가는 거리는 0 heap = [[0, v]] # 힙에 [거리, 시작 마을]을 넣어 시작 # 힙이 빌 때까지 반복 while heap: w, v = heapq.heappop(heap) # 힙에서 현재까지의 거리 w와 현재 마을 v를 꺼냄 if w > visited[v]: # 이미 방문한 마을이면 넘어감 continue # 현재 마을에서 이동할 수 있는 모든 경로에 대해 처리 for nv, nw in graph[v]: tmp = w + nw # 현재 거리 w에 다음 마을까지의 거리 nw를 더함 if tmp < visited[nv]: # 더 짧은 경로가 있다면 업데이트 visited[nv] = tmp heapq.heappush(heap, [tmp, nv]) # 새로운 경로를 힙에 추가 return visited # 시작 마을에서 다른 마을까지의 최단 거리를 반환 # 파티에서 집까지 왕복하는 데 걸리는 시간이 가장 긴 학생의 왕복 시간 구하기 ans = 0 dij1 = dijkstra(x) # x 마을에서 모든 마을까지 가는 최단 거리 (파티에서 집으로 가는 거리) for i in range(1, n + 1): if i == x: # 자기 자신으로의 왕복은 계산할 필요가 없으므로 패스 continue dij2 = dijkstra(i) # i 마을에서 x 마을까지 가는 최단 거리 (집에서 파티로 가는 거리) ans = max(ans, dij2[x] + dij1[i]) # 가장 오래 걸리는 왕복 시간을 계산 # 최종적으로 가장 긴 왕복 시간을 출력 print(ans)2.C++
#include <iostream> #include <vector> #include <queue> #include <tuple> #include <algorithm> using namespace std; // 다익스트라 알고리즘을 사용해 시작 노드 v에서 목표 노드 target까지의 최단 경로를 구함 int dijkstra(int v, const int target, const int n, const vector<vector<pair<int, int>>>& graph) { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // 최소 힙을 위한 우선순위 큐 vector<int> visited(n+1); // 방문 여부를 기록하는 배열 int w = 0; pq.push(make_pair(0, v)); // 시작 노드를 큐에 삽입 (거리, 노드 번호) while (!pq.empty()) { tie(w, v) = pq.top(); // 현재 노드와 그까지의 거리 pq.pop(); // 목표 노드에 도달하면 그때의 거리를 반환 if (v == target) return w; visited[v] = 1; // 현재 노드를 방문 처리 // 현재 노드와 연결된 모든 노드를 탐색 for (auto g : graph[v]) { int nv = g.first; // 다음 노드 int nw = g.second; // 다음 노드까지의 가중치 // 방문하지 않은 노드에 대해서만 큐에 추가 if (!visited[nv]) { pq.push(make_pair(nw + w, nv)); // 누적된 거리를 큐에 삽입 } } } return -1; // 목표 노드에 도달할 수 없는 경우 (여기서는 없을 것으로 가정) } int main() { int n, m, x; cin >> n >> m >> x; // n: 노드 수, m: 간선 수, x: 목적지 노드 vector<vector<pair<int, int>>> graph(n+1); // 그래프 저장 (인접 리스트) // 그래프 입력 while (m--) { int u, v, w; cin >> u >> v >> w; // u에서 v로 가는 가중치 w의 간선 입력 graph[u].push_back(make_pair(v, w)); } vector<int> times(n+1); // 각 노드에서 출발해 돌아오는 시간을 저장할 벡터 // 각 노드에서 x로 갔다가 돌아오는 데 걸리는 시간 계산 for (int i = 1; i <= n; i++) { int time = 0; time += dijkstra(i, x, n, graph); // i에서 x까지 가는 최단 경로 time += dijkstra(x, i, n, graph); // x에서 i로 돌아오는 최단 경로 times[i] = time; // 해당 노드의 왕복 시간 저장 } // 가장 오래 걸리는 왕복 시간 출력 cout << *max_element(times.begin(), times.end()); return 0; }풀이
- 문제 분석:
- 각 마을 간의 도로가 주어지고, 도로는 방향성(단방향)을 가진다.
- 주어진 특정 마을(파티가 열리는 마을)로 갔다가 다시 원래 마을로 돌아오는 데 걸리는 시간을 구해야 한다.
- 각 학생이 자기 마을에서 파티가 열리는 마을까지 갔다가 돌아오는 데 걸리는 시간 중 최댓값을 구하는 것이 목표이다.
- 다익스트라 알고리즘:
- 다익스트라 알고리즘을 사용하여, 한 노드에서 다른 모든 노드로의 최단 경로를 구할 수 있다.
- 두 번의 다익스트라 알고리즘을 사용하여 문제를 해결할 수 있다:
- 각 마을에서 파티가 열리는 마을까지의 최단 경로를 구한다.
- 파티가 열리는 마을에서 각 마을로 돌아가는 최단 경로를 구한다.
- 출력:
- 각 학생의 왕복 경로 시간을 계산하고, 그 중 가장 큰 값을 출력한다.
'Algorithm > Baekjoon' 카테고리의 다른 글
[C++] 1629번 곱셈 (0) 2024.10.13 [Python][C++] 1504번 특정한 최단 경로 (7) 2024.10.09 [C++] 1167번 트리의 지름 (1) 2024.09.25 [Python][C++] 1149번 RGB거리 (2) 2024.09.17 [Python][C++] 1043번 거짓말 (0) 2024.09.17 - 문제 분석: