566 words
3 minutes
[BOJ] 보석 줍기
| TimeLimit | MemoryLimit | Condition | TAG |
|---|---|---|---|
| 2s | 128MB | (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
*/

