문제에 대한 다결정 해를 설명합니다. 몇 가지 정의를 소개합시다. 우리는 나타내는 것이다 : 그래프의 정점의
- 설정을
V
에 의해, E
에 의해 그래프의 모서리의 설정 T
에 의해 MST 가장자리의 집합입니다.
- 정점 간 그래프의 가장자리
v
및 u
은 {v, u}
입니다.
- 가장자리의 무게
e
은 W(e)
이고 MST의 무게는 W(T)
이다.
이다 T
이 속하는 v
및 u
간의 간단한 경로에 큰 가중치 에지 같다 MaxEdge(v, u)
기능을 고려하자. 최대 가중치가있는 여러 개의 가장자리가있는 경우 MaxEdge(v, u)
과 같을 수 있습니다.
, 우리는 가장자리
x = {p, q}
을 찾을 필요, 그 두 번째 최고의 MST를 확인하는 방법은 다음과 같습니다
x
는 T
에 속하지 않습니다.
- 기능
W(x) - W(MaxEdge(p, q))
은 가능한 최소입니다.
그것은 최고의 두 번째 MST가 T
에서 MaxEdge(p, q)
을 제거하고 T
에 x = {p, q}
을 추가하여 구성 할 수 있음을 증명하는 것이 가능하다.
이제 MaxEdge(p, q)
을 O(log|V|)
에 계산할 수있는 데이터 구조를 만들자.
트리의 루트를 선택하자. T
(모든 정점이 될 수 있음). 꼭지점 v
과 루트 인 꼭지점 깊이 v
사이의 단순 경로에서 가장자리 수를 호출하고 Depth(v)
으로 지정합니다. O(|V|)
에있는 모든 정점에 대해 Depth(v)
을 depth first search으로 계산할 수 있습니다.Depth(v) - 2^i
동일한 깊이와 부모 정점 같다
Parent(v, i)
는, 정점 v
의 (비 직접 부모가 될 수 있음) : MaxEdge(p, q)
을 계산하는 데 도움이 될 것입니다 의 두 가지 기능을 계산하자
, .
MaxParentEdge(v, i)
이고, 이는 MaxEdge(v, Parent(v, i))
과 동일하다.
둘 다 O(|V|log|V|)
에 암기를 갖는 반복 함수에 의해 계산 될 수 있습니다.
// Assumes that 2^i <= Depth(v)
Vertex Parent(Vertex v, Vertex i) {
if (i == 0) return direct_parent[v];
if (Memorized(v, i)) return memorized_parent[v][i];
memorized_parent[v][i] = Parent(Parent(v, i - 1), i - 1);
return memorized_parent[v][i];
}
Edge MaxParentEdge(Vertex v, Vertex i) {
if (i == 0) return Edge(v, direct_parent[v]);
if (Memorized(v, i)) return memorized_parent_edge[v][i];
Edge e1 = MaxParentEdge(v, i - 1);
Edge e2 = MaxParentEdge(Parent(v, i - 1), i - 1);
if (W(e1) > W(e2)) {
memorized_parent_edge[v][i] = e1;
} else {
memorized_parent_edge[v][i] = e2;
}
return memorized_parent_edge[v][i];
}
MaxEdge(p, q)
을 계산하기 전에 최종 정의를 소개하겠습니다. Lca(v, u)
은 루트 트리 T
에서 정점 v
및 u
의 lowest common ancestor을 나타냅니다. Lca(v, u)
쿼리를 O(log|V|)
또는 심지어 O(1)
에 계산할 수있는 잘 알려진 데이터 구조가 많이 있습니다 (Wikipedia에서 기사 목록을 찾을 수 있습니다). p
에서 Lca(p, q)
에 Lca(p, q)
에서 q
에 :
우리는 두 부분으로 p
와 q
사이의 경로를 나눕니다 MaxEdge(p, q)
을 계산합니다. 이 각각의 부분은 정점에서부터 부모까지의 경로처럼 보입니다. 따라서 Parent(v, i)
및 MaxParentEdge(v, i)
함수를 사용하여이 부분에 MaxEdge
을 계산할 수 있습니다.
Edge MaxEdge(Vertex p, Vertex q) {
Vertex mid = Lca(p, q);
if (p == mid || q == mid) {
if (q == mid) return QuickMaxEdge(p, mid);
return QuickMaxEdge(q, mid);
}
// p != mid and q != mid
Edge e1 = QuickMaxEdge(p, mid);
Edge e2 = QuickMaxEdge(q, mid);
if (W(e1) > W(e2)) return e1;
return e2;
}
Edge QuickMaxEdge(Vertex v, Vertex parent_v) {
Edge maxe = direct_parent[v];
string binary = BinaryRepresentation(Depth(v) - Depth(parent_v));
for (int i = 0; i < binary.size(); ++i) {
if (binary[i] == '1') {
Edge e = MaxParentEdge(v, i);
if (W(e) > W(maxe)) maxe = e;
v = Parent(v, i);
}
}
return maxe;
}
기본적 QuickMaxEdge(v, parent_v)
길이 2^i
의 점프가 parent_v
및 v
사이의 간격을 덮도록 작동하지. 점프하는 동안 미리 계산 된 MaxParentEdge(v, i)
값을 사용하여 답변을 업데이트합니다.
MaxParentEdge(v, i)
및 Parent(v, i)
초기 문제에 대한 O(|E|log|V|)
솔루션으로 우리를 인도하는 O(log|V|)
에 MaxEdge(p, q)
작품, 미리 계산 된 것을 고려. T
에 속하지 않는 모든 가장자리를 반복하고 각각에 대해 W(e) - MaxEdge(p, q)
을 계산하면됩니다.
psedocode를 추가 할 수 있다면 더 적절하고 사람들이 쉽게 대답을 이해할 수 있습니다. – arunmoezhi
이유가 무엇인지 자세히 설명해 주시겠습니까? – Math