hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie
PS/PS Log

23.09.19. 풀었던 문제들

PS/PS Log

23.09.19. 풀었던 문제들

Programmers Lv. 3 여행경로, 17분

 그냥 DFS 돌리면 되는 문제. 단 각각의 vertex가 string으로 표현되는 점과 [사용한 표]를 어떻게 표기할지에 대해 유의해야 한다. 뭐.. 정석 DFS처럼 각 ticket의 index를 visit했는지 안했는지를 표기할 수 있긴 한데. 결국 alphabet 순서로 DFS + edges를 만들어야 하기 때문에 map을 사용해야 할 것 같다.

 처음에는 multiset을 썼었는데, DFS를 위해 multiset에서 element를 빼고 넣는 과정에서 계속 같은 위치를 참조하는 것 같았다. (무한루프) 그래서 map of map을 썼다. edges[i]는 i에 인접한 공항들의 map 목록이고, 이것은 [도착지 이름, 같은 표가 몇 개인지]를 나타낸다.

 나머지는 뭐.. 코드 보면 이해하기 쉬울 것 같다.

int max_depth;
map<string, map<string, int>> edges; // edges[i] : i에 인접한 공항들
vector<string> result;
bool DFS(int cur_depth, string cur_airport){
if(cur_depth == max_depth){
return true;
}
for(auto &[name, count] : edges[cur_airport]){
if(count == 0) continue;
edges[cur_airport][name]--;
result[cur_depth + 1] = name;
bool hasAnswer = DFS(cur_depth+1, name);
if(hasAnswer) return true;
edges[cur_airport][name]++;
}
return false;
}
vector<string> solution(vector<vector<string>> tickets) {
max_depth = (int) tickets.size();
for(vector<string> ticket : tickets){
string src = ticket[0], dest = ticket[1];
edges[src][dest]++;
}
result.resize(max_depth + 1);
result[0] = "ICN";
DFS(0, "ICN");
return result;
}

 

시간복잡도

 ticket size를 n이라 하면, edge에 넣는 데 O(loglogn), 꺼내는 데도 O(loglogn)이다. 어떤 출발지로부터 도착지 목록을 가져오는 데는 O(logn)이 걸리고, 이를 순회하는 데 O(nlogn)이 걸린다.

 DFS 자체는, vertex가 O(n)이므로 O(n)이다. 따라서 O(nlogn).

 

후기

 참고로 예전에 풀었던 코드는 다음과 같다. 각 DFS에서 모든 ticket을 보기 때문에 시간이 너무 오래 걸릴 것이다! input이 작아 해결되지만 input이 큰 경우는 해결되지 않을 것. 그리고 코드 자체도 훨씬 간단하다.

vector<string> answer;
bool cmp(vector<string> &a, vector<string>&b){
for(int i = 0; i<a.size(); i++){
if(a[i] < b[i]) return true;
else if(a[i] > b[i]) return false;
else continue;
}
}
void DFS(int depth, int max_depth, string dep, vector<bool>& visited, vector<vector<string>>& tickets, vector<string>& result){
if(depth == max_depth){
if(answer.empty()) answer = result;
answer = cmp(answer, result)? answer : result;
return;
}
for(int i = 0; i<max_depth; i++){
if(tickets[i][0] == dep && !visited[i]){
visited[i] = true;
result[depth + 1] = tickets[i][1];
DFS(depth+1, max_depth, tickets[i][1], visited, tickets, result);
visited[i] = false;
}
}
}
vector<string> solution(vector<vector<string>> tickets) {
int size = tickets.size();
vector<string> result(size + 1); result[0] = "ICN";
vector<bool> visited(size, false);
DFS(0, tickets.size(), "ICN", visited, tickets, result);
return answer;
}

 

 

 

 

 

저작자표시 (새창열림)

'PS > PS Log' 카테고리의 다른 글

23.09.24. 풀었던 문제들  (0) 2023.09.25
23.09.23. 풀었던 문제들  (0) 2023.09.25
23.09.17. 풀었던 문제들  (0) 2023.09.18
23.09.14. 풀었던 문제들  (0) 2023.09.14
23.09.12. 풀었던 문제들  (0) 2023.09.12
  • Programmers Lv. 3 여행경로, 17분
  • 후기
hyelie
hyelie

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.