문제풀이/백준oj
[백준OJ] 1939번 중량제한
Hyeon-Uk
2021. 3. 17. 14:38
반응형
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();
}
반응형