Compy's Blog
566 words
3 minutes
[BOJ] 보석 줍기
2026-03-17

보석 줍기

TimeLimitMemoryLimitConditionTAG
2s128MB(1 ≤ n ≤ 100,
1 ≤ m ≤ 1000
1 ≤ K ≤ 14
1 <= c <= 100)
BFS

솔직히 문제 자체는 쉬웠는데, bit count 세는 로직에서 k를 n으로 적어놓고 오류를 못 찾아서 많이 오래걸린 케이스이다.

최적화 개념에서 bit masking을 활용한다.

정답 코드
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <sstream>
#include <iomanip>
#include <string>
#include <numeric>
#include <unordered_set>
#include <unordered_map>
#include <climits>
#include <math.h>
using namespace std;
using ll = long long;
using ld = long double;
ll MOD = 1'000'000'000 + 7;

using namespace std;

int n, m, k;

int strength[101][101];
// 걍 viist처리를 몇 번 움직였는가? + 몇 번째 보석을 가졌는가? 에 대한 visit처리만 하면 될드 ㅅ? 근데 최대가 14개인데 이걸르 어케 처리하냐!!! 바로 bit masking이지 아무래도 ㅇㅇ

bool visited[101][20001];


vector<int> gemIsland;

int countOne(int v){
    int result = 0;
    
    int flag = 1;
    while(flag < 1 << k){ // 아니 쉬발 이거였다고? 와 이걸 왜 이따구로 썻냐
        
     
        result += (flag & v) ? 1 : 0;
        flag <<= 1;
    }
    
//    cout << "result: " << result << "\n";
    return result;
    
}


int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
  
    cin >> n >> m >> k;
    bool start_gem = 0;
    for(int i = 0; i < k; i++) {
        int tmp;
        cin >> tmp;
        
        gemIsland.push_back(tmp-1);
        if(tmp == 1)start_gem = true;
    }
    
    
    
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        
        
        strength[a-1][b-1] = c;
        strength[b-1][a-1] = c;
    }
    
    for(int i = 0;  i < 101; i++){
        for(int j = 0; j < 20001; j++){
            visited[i][j] = false;
        }
    }
    
    
    queue<pair<int, int>> q;
    
    q.push({0, 0});
    int result = start_gem;
    
    while(!q.empty()){
        auto [node, current_visited] = q.front(); q.pop();
        
        int currentCount = countOne(current_visited); // 허허 ㅅ발
        
        
        if(node == 0){
            result = max(result, currentCount);
//            int flag = 1;
//            while(flag < 1 << n){
//             
//                if(flag & current_visited) cout << 1;
//                else cout << 0;
//                flag <<= 1;
//            }
//            cout << " : " << countOne(current_visited) <<" \n\n";
            
        }
        
        
        int origin_current_visited = current_visited;
        
        
        for(int i = 0; i < n; i++){
            if(!strength[node][i]) continue; // 0이면 안 들어갈곤데
            if(strength[node][i] < currentCount) continue;
            current_visited = origin_current_visited;
            
            
            if(!visited[i][current_visited]){
                visited[i][current_visited] = true;
                q.push({i, current_visited});
            }
            
            
            for(int j = 0; j < k; j++){
                if(gemIsland[j] == i){
                    current_visited |= 1 << j;
                    break;
                }
            }
            
            
            if(!visited[i][current_visited]){
                
                visited[i][current_visited] = true;
                q.push({i, current_visited});
            }
        }
    }

    
    cout << result;
    return 0;
}

/*
 1 0 1
 1
 
 
 2 1 2
 1
 2
 2 1 3
 
 6 5 6
 1
 2
 3
 4
 5
 6
 1 2 1
 1 3 2
 1 4 3
 1 5 4
 1 6 5
 
 
 6 5 6
 1
 2
 3
 4
 5
 6
 1 2 1
 1 3 1
 1 4 1
 1 5 4
 1 6 5
 */

[BOJ] 보석 줍기
https://compy07.github.io/Blog/posts/boj/2001/
Author
뒹굴뒹굴 이정훈 공부방
Published at
2026-03-17