N개의 노드가 있는 하나의 무방향 연결 그래프가 있다고 가정합니다. 이 노드는 0, 1, 2, ..., N-1로 레이블이 지정됩니다. 그래프 길이는 N이고 j는 노드 i와 j가 연결된 경우에만 목록 그래프[i]에 있는 i와 정확히 한 번 같지 않습니다. 모든 노드를 방문하는 최단 경로의 길이를 찾아야 합니다. 모든 노드에서 시작 및 중지할 수 있으며 노드를 여러 번 다시 방문할 수 있으며 가장자리를 재사용할 수 있습니다.
따라서 입력이 [[1],[0,2,4],[1,3,4],[2],[1,2]]와 같으면 출력은 4가 됩니다. 이제 여기에 하나가 가능합니다. 경로는 [0,1,4,2,3]입니다.
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
-
하나의 대기열 정의
-
n :=그래프 크기
-
요구:=2^(n - 1)
-
하나의 지도 정의
-
initialize i :=0의 경우, i
-
q에 {0 OR (2^i), i} 삽입
-
-
n이 1과 같으면 -
-
0 반환
-
-
initialize lvl :=1의 경우 q가 비어 있지 않으면 업데이트(lvl을 1씩 증가)하고 -
를 수행합니다.-
sz :=q의 크기
-
sz가 0이 아닌 동안 각 반복에서 sz를 1씩 줄입니다. -
-
배열 정의 curr =q
의 앞 요소 -
q에서 요소 삭제
-
for initialize i :=0, i
-
유 :=그래프[curr[1], i]
-
newMask :=(curr[0] OR 2^u)
-
newMask가 req와 같으면 -
-
레벨을 반환
-
-
방문[u]의 호출 횟수(newMask)인 경우 -
-
다음 부분은 무시하고 다음 반복으로 건너뜁니다.
-
-
방문[u]
에 newMask 삽입 -
q에 {newMask, u} 삽입
-
-
-
-
반환 -1
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예
#include <bits/stdc++.h> using namespace std; void print_vector(vector<auto> v){ cout << "["; for(int i = 0; i<v.size(); i++){ cout << v[i] << ", "; } cout << "]"<<endl; } class Solution { public: int shortestPathLength(vector<vector<int> >& graph){ queue<vector<int> > q; int n = graph.size(); int req = (1 << n) - 1; map<int, set<int> > visited; for (int i = 0; i < n; i++) { q.push({ 0 | (1 << i), i }); } if (n == 1) return 0; for (int lvl = 1; !q.empty(); lvl++) { int sz = q.size(); while (sz--) { vector<int> curr = q.front(); q.pop(); for (int i = 0; i < graph[curr[1]].size(); i++) { int u = graph[curr[1]][i]; int newMask = (curr[0] | (1 << u)); if (newMask == req) return lvl; if (visited[u].count(newMask)) continue; visited[u].insert(newMask); q.push({ newMask, u }); } } } return -1; } }; main(){ Solution ob; vector<vector<int>> v = {{1},{0,2,4},{1,3,4},{2},{1,2}}; cout << (ob.shortestPathLength(v)); }
입력
{{1},{0,2,4},{1,3,4},{2},{1,2}}
출력
4