https://school.programmers.co.kr/learn/courses/30/lessons/81304
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
생각의 흐름
- 최단거리 -> 다익스트라 사용
- 함정 활성화, 비활성화만 구분하면 되지 않을까?(실패)
- 만약 함정 양쪽이 활성화 되어 있는 경우 -> 함정 활성화가 되어있지만 원래 방향으로 이동하기 때문
- 함정 활성화 상태를 비트마스킹으로 저장하자
- way에 정방향 간선은 true로 역방향 간선은 false로 저장을 하자
- 일반 노드와 비활성 함정 노드는 false로 같은 취급 활성 함정 노드만 true로 취급하자
- 둘 중 하나만 활성화 되어 있는 경우 역방향 간선으로만 움직이므로 XOR을 이용하자
해설
이 문제는 경우가 4가지가 나오게 된다. (비활성 함정 노드는 일반 노드 취급)
1. 일반 노드 -> 일반 노드
2. 일반 노드 -> 활성 함정 노드
3. 활성 함정 노드 -> 비활성 함정 노드
4. 활성 함정 노드 -> 활성 함정 노드

1 -> 2로 가는 경로의 경우
1번은 비활성 노드 = false
2번은 만약 활성화 = true
false == true -> false이므로 1->2로 가는 간선은 true일때만 이용가능하여 이동하지 못하게 된다.
3->2로 가는 경우
2번이 활성화 = true
3번이 활성화 = true
true == true -> true 이므로 3->2로 가는 간선은 정방향 이므로 이동 가능하게 된다.
2->3으로 가는 경우
2번이 활성화 = true
3번이 비활성화 = false
true == false -> false 이므로 2->3은 역방향 간선이어서 이동 가능하게 된다.
코드
더보기
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
vector<tuple<int, int, bool> > way[1001];
int dist[1001][1<<11];
int trapper[1001];
struct dat{
int cost, node, vst_trap;
bool operator<(const struct dat& d) const{
return cost > d.cost;
}
};
bool cmp(vector<int>& a, vector<int>& b){
return a[2] < b[2];
}
int dijkstra(int start,int end){
priority_queue<dat> pq;
dist[start][0]=0;
pq.push({0,start,0});
while(!pq.empty()){
int node=pq.top().node;
int cost=pq.top().cost;
int vst_trap=pq.top().vst_trap;
pq.pop();
if(dist[node][vst_trap] < cost)
continue;
if(node == end)
return cost;
for(int i=0,sz=way[node].size();i<sz;++i){
int next,ncost;
int nstate = vst_trap;
bool can_vst;
tie(next,ncost,can_vst) = way[node][i];
ncost+=cost;
can_vst = can_vst == ((1 & nstate >> trapper[next]) == (1 & nstate >> trapper[node]));
if(trapper[next])
nstate = (1 & nstate >> trapper[next]) ? (nstate - (1 << trapper[next])) : (nstate | 1 << trapper[next]);
if(dist[next][nstate] <= ncost || !can_vst)
continue;
dist[next][nstate]=ncost;
pq.push({ncost,next,nstate});
}
}
return -1;
}
int solution(int n, int start, int end, vector<vector<int>> roads, vector<int> traps) {
int answer = 0;
fill(&dist[0][0],&dist[n][1<<11],987'654'321);
sort(roads.begin(),roads.end(), cmp);
for(int i=0,sz=traps.size();i<sz;++i){
trapper[traps[i]]=i+1;
}
for(int i=0,sz=roads.size();i<sz;++i){
int st = roads[i][0];
int ed = roads[i][1];
int cost = roads[i][2];
way[st].push_back({ed,cost,true});
if(trapper[st] || trapper[ed])
way[ed].push_back({st,cost,false});
}
answer=dijkstra(start,end);
return answer;
}

728x90
'알고리즘 > 프로그래머스 문제' 카테고리의 다른 글
| [Level 3] - 자물쇠와 열쇠 (0) | 2023.07.10 |
|---|---|
| [ALGORITHM] LEVEL3 2021 카카오 채용연계형 인턴십 - 표 편집 (0) | 2023.01.06 |
| [ALGORITHM] LEVEL3 2022 KAKAO BLIND RECRUITMENT - 양과 늑대 (0) | 2022.12.30 |
| [ALGORITHM] LEVEL3 2022 KAKAO BLIND RECRUITMENT - 파괴되지 않은 건물 (0) | 2022.12.28 |
| [ALGORITHM] LEVEL3 2022 KAKAO BLIND RECRUITMENT - 사라지는 발판 (0) | 2022.12.23 |
댓글