-
반응형
1939번: 중량제한
첫째 줄에 N, M(1≤M≤100,000)이 주어진다. 다음 M개의 줄에는 다리에 대한 정보를 나타내는 세 정수 A, B(1≤A, B≤N), C(1≤C≤1,000,000,000)가 주어진다. 이는 A번 섬과 B번 섬 사이에 중량제한이 C인 다리
www.acmicpc.net
-풀이-
출발지점에서 w만큼의 무게를 들고 시작점->도착점까지 도달할 수 있는지 없는지에 대한 bfs를 세워둔뒤, w에 대한 이분탐색을 실시한다.
만약 w만큼의 무게를 시작지점->도착지점까지 도달이 가능하다면, 무게를 올려도 되므로 left를 갱신시키고, 도달할 수 없으면 무게를 줄여야하므로 right를 갱신시키며 탐색을 하면, 물품들의 중량의 최댓값을 구할 수 있다.
-시간 복잡도-
w에 대한 이분탐색은 O(logC) (C=최대 중량 ) 이 되는것이고 , 각 이분탐색마다의 bfs탐색은 O(N)이 되므로, 최종 시간복잡도는 O(NlogC)가 된다.
-코드-
#include<iostream> #include<algorithm> #include<vector> #include<queue> #include<cstring> using namespace std; int n, m,st,dest; int Max=0; vector<pair<int,int>> edge[100001]; bool visited[100001]; void input() { cin >> n >> m; for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; edge[a].push_back({ b,c }); edge[b].push_back({ a,c }); Max = max(Max, c); } cin >> st >> dest; } bool bfs(int weight) { queue <int> q; q.push(st); visited[st] = true; while (!q.empty()) { int now = q.front(); q.pop(); //도착할 수 있으면 true 리턴 if (now == dest) { return true; } for (int i = 0; i < edge[now].size(); i++) { int next = edge[now][i].first; int maxWeight = edge[now][i].second; //현재 중량을 들고 도로를 통과 가능하다면 push if (!visited[next] && weight <= maxWeight) { visited[next] = true; q.push(next); } } } //못가면 false return false; } void solve() { int left = 0; int right = Max; while (left <= right) { memset(visited, false, sizeof(visited)); int middle = (left + right) / 2; //성공하면 무게를 좀 더 올려도 되므로 left업데이트 if (bfs(middle)) { left = middle+1; } //실패하면 무게를 줄여야하므로 right업데이트 else { right = middle - 1; } } cout << right << "\n"; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); input(); solve(); }
반응형'문제풀이 > 백준oj' 카테고리의 다른 글
[백준OJ] 8012번 한동이는 영업사원! (0) 2021.03.24 [백준OJ] 14002번 가장 긴 증가하는 부분 수열 4 , 14003번 가장 긴 증가하는 부분 수열 5 (0) 2021.03.22 [백준OJ] 5884번 감시카메라 (0) 2021.03.17 [백준OJ] 13904번 과제 (0) 2021.03.15 [백준OJ] 7562번 나이트의 이동 (0) 2021.03.11 댓글