각 인덱스 i가 도시를 나타내는 동일한 크기의 두 목록 cost_from 및 cost_to가 있다고 가정합니다. 그것은 도시 i에서 j까지 일방통행 도로를 만들고 있으며 비용은 비용_from[i] + 비용_to[j]입니다. 또한 각 모서리에 [x, y]가 포함된 모서리 목록이 있으며 이는 x에서 y로 가는 일방통행 도로가 이미 있음을 나타냅니다. 0번 도시에서 아무 도시로 가려면 필요한 도로를 건설하는 데 필요한 최소 비용을 찾아야 합니다.
따라서 입력이 cost_from =[6, 2, 2, 12] cost_to =[2, 2, 3, 2] edge =[[0, 3]]인 경우 출력은 13이 됩니다. 비용 9로 0에서 2로. 그 후 비용 4로 2에서 1로 갈 수 있습니다. 그리고 이미 0에서 3으로 가는 길이 있습니다. 따라서 합계는 9 + 4 =13입니다.피>
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
- n :=cost_from 의 크기
- ret :=0
- 두 개의 지도 가장자리 및 가장자리 정의
- 모든 항목에 대해 g:
- 가장자리의 끝에 삽입[1][it[0]]
- 가장자리[it[1]] 끝에 삽입[0]
- from_cost :=정보
- 방문한 세트와 도달 가능한 다른 세트 정의
- 함수 dfs를 정의하면 숫자 i
- 가 필요합니다.
- 방문하지 않고 연결할 수 없는 경우:
- 방문한 항목에 i 삽입
- 가장자리[i]의 모든 j에 대해 다음을 수행합니다.
- dfs(j)
- po 끝에 i 삽입
- 방문하지 않고 연결할 수 없는 경우:
- 함수 dfs2를 정의합니다. 여기에는 숫자 i가 필요합니다.
- 내가 방문하면
- 참을 반환
- 연결 가능한 경우
- 거짓 반환
- 방문한 것으로 표시하고 연결 가능한 것으로 표시
- ret :=사실
- redges[i]의 모든 j에 대해 수행
- ret :+ ret AND dfs2(j)
- 반환
- 하나의 대기열 정의
- 연결 가능한 곳에 0을 삽입하고 q에 0을 삽입
- 동안(q는 비어 있지 않음) 다음을 수행합니다.
- 노드:=q의 첫 번째 요소
- q에서 요소 삭제
- 가장자리[노드]
- 의 각 i에 대해
- 연결할 수 없는 경우:
- 연결 가능한 위치에 i 삽입, q에 i 삽입
- from_cost :=from_cost 및 비용_from[노드]의 최소값
- 연결할 수 없는 경우:
- global_min :=cost_from의 최소 요소
- ret :=ret + from_cost - global_min
- 배열 위치 정의
- 0에서 n 사이의 i에 대해
- dfs(i)
- 배열 반전
- 포에 있는 각 i에 대해 다음을 수행합니다.
- 연결 가능한 경우:
- 다음 반복으로 이동
- 방문한 배열 지우기
- 초기:=dfs2(i)
- 이니셜이 참이면 다음을 수행합니다.
- 최고:=inf
- 방문한 각 j에 대해:
- best :=best와 cost_to[j]의 최소값
- ret :=ret + global_min + 최상
- 연결 가능한 경우:
- 반환
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예시
#include
using namespace std;
class Solution {
public:
int solve(vector& costs_from, vector& costs_to, vector>& g) {
int n = costs_from.size();
int ret = 0;
map> edges;
map> redges;
for (auto& it : g) {
edges[it[0]].push_back(it[1]);
redges[it[1]].push_back(it[0]);
}
int from_cost = INT_MAX;
set visited;
set reachable;
queue q;
reachable.insert(0);
q.push(0);
while (!q.empty()) {
int node = q.front();
q.pop();
for (int i : edges[node]) {
if (!reachable.count(i)) {
reachable.insert(i);
q.push(i);
}
}
from_cost = min(from_cost, costs_from[node]);
}
int global_min = *min_element(costs_from.begin(), costs_from.end());
ret += from_cost - global_min;
vector po;
function dfs;
dfs = [&](int i) {
if (!visited.count(i) && !reachable.count(i)) {
visited.insert(i);
for (int j : edges[i]) {
dfs(j);
}
po.push_back(i);
}
};
for (int i = 0; i < n; i++) dfs(i);
reverse(po.begin(), po.end());
function dfs2;
dfs2 = [&](int i) {
if (visited.count(i)) return true;
if (reachable.count(i)) return false;
visited.insert(i);
reachable.insert(i);
bool ret = true;
for (int j : redges[i]) {
ret &= dfs2(j);
}
return ret;
};
for (int i : po) {
if (reachable.count(i)) continue;
visited.clear();
bool initial = dfs2(i);
if (initial) {
int best = INT_MAX;
for (int j : visited) {
best = min(best, costs_to[j]);
}
ret += global_min + best;
}
}
return ret;
}
};
int solve(vector& costs_from, vector& costs_to, vector>& edges) {
return (new Solution())->solve(costs_from, costs_to, edges);
}
int main(){
vector costs_from = {6, 2, 2, 12};
vector costs_to = {2, 2, 3, 2};
vector> edges = {{0, 3}};
cout << solve(costs_from, costs_to, edges);
} 입력
{6, 2, 2, 12}, {2, 2, 3, 2}, {{0, 3}} 출력
13