2012-05-22 3 views
4

두 부분 그래프에서 왼쪽에는 n 개의 노드가 있고 오른쪽에는 m 개의 노드가 있습니다. 노드는 1에서 n 및 1에서 m까지 정렬됩니다. 왼쪽의 노드는 오른쪽의 노드에 연결됩니다. 모든 노드가 연결되어 있지 않습니다. 예 :이분 그래프의 교차 수

1 is connected to 4 

2 is connected to 3 

3 is connected to 2 

3 is connected to 1 

그래프에 몇 개의 교차점이 있는지 알고 싶습니다 (여기 5 교차점). 비슷한 문제가 있습니다. SPOJ

일부 사용자가 언급 한 것처럼 이진 인덱스 트리를 사용하여이 문제를 해결할 수있는 방법을 알고 싶습니다. 나는 O (n^2) algo로 풀리고 TLE을 얻고있다.

이것은 숙제가 아닙니다. 어제 BIT를 배웠고 몇 가지 문제를 찾고 있었기 때문에이 문제를 발견했습니다. 트릭을 말해줘. 전체 프로그램을 작성하지 마십시오.

+0

문제 도메인에 대해 다시 생각해보십시오. 그래프 노드는 정렬되지 않으므로 위의 예제 그래프를 전혀 교차하지 않고 그릴 수 있습니다 (두 개의 열 3,1,2,4 및 1,2,4,3을 그립니다)). 따라서 노드를 그리는 방법에 대한 기하학적 제한을 두거나 최소 교차 수를 요구해야합니다 (예를 들어 수정해야합니다). – flolo

답변

3

왼쪽 노드의 인덱스를 기준으로 에지를 정렬 한 다음 오른쪽 노드의 인덱스를 사용하여 왼쪽 노드의 인덱스를 동일하게 정렬합니다. 오른쪽 노드의 인덱스를보십시오. 그래프의 각 교차점은이 정렬 된 목록에서 순서가 맞지 않는 한 쌍의 색인에 해당합니다. 그런 "순서가 맞지 않는"쌍을 세는 것만으로도 충분합니다.

정렬 된 목록의 오른쪽 노드의 각 색인을 순차적으로 이진 색인 트리에 삽입하십시오. 각 삽입 후에 O (log (m)) 시간에 이미 트리에있는 더 큰 인덱스가 몇 개인 지 찾을 수 있습니다. 그래서 전체 알고리즘의 시간 복잡도는 정렬을위한 O (h * log (h))와 숫자를 계산하기위한 O (h * log (m)) O (h * 인덱스 반전 수 (여기에서 'h'는 모서리 수)입니다. 기수 정렬이나 버킷 정렬을 사용하여 이것을 O (h * log (m))로 향상시킬 수 있습니다.


업데이트 : 안드로이드 디코딩 된에 의해 발견으로

, 역전 문제의 수를 병합 정렬을 기반으로하는 분할 정복 알고리즘을 사용하여 해결할 수 있습니다. 자세한 내용은 here을 참조하십시오. 이 접근법은 이진 인덱스 트리 O (h * log (m))를 사용하는 것의 복잡성보다는 시간 복잡성 O (h * log (h))가 크지 만 에지 수가 많지 않은 스파 스 그래프의 경우 메모리가 더 적고 캐시 친화적이기 때문에 더 빨라야합니다.

병합 중에 중복 항목을 제거하면 병합 정렬 방식의 복잡성이 O (h * log (m))로 향상 될 수 있습니다. 이렇게하려면 (value, numberOfInstances) 쌍에 병합 정렬을 적용합니다. 여기서 인접한 동일한 값이 적절한 'numberOfInstances'가있는 하나의 항목으로 결합됩니다. 최악의 경우, 첫 번째 로그 (m) 병합 통과에 대해 중복이 제거되지 않습니다. 이것은 O (h * log (m))의 복잡성을가집니다. 중복이 O (h) 시간에 빨리 제거되면 log (n)까지의 패스가 유지됩니다.

이진 인덱스 트리 사용 세부 정보 :

이진 인덱스 트리를 구현 가장 큰 값부터 시작하여 트리의 인덱스를 반환 할 수 있습니다 주어진 키 (가장 큰 하나 그 -> 인덱스 0, 두 번째로 큰 - > 색인 1, ...). 그런 다음 각 요소를 트리에 삽입 한 후 색인을 요청하십시오. 정렬 된 목록에서이 요소의 왼쪽에있는 큰 값의 수가됩니다.

자세한 내용 : 이진 색인 트리는 검색 트리로 구현 될 수 있으며 각 노드는 하위 노드의 카운터로 보강됩니다. 중복 요소에 대해 별도의 노드를 만들지 말고 각각에 대한 자손 노드 카운터를 업데이트하십시오.어떤 키에 대한 색인을 요구할 때, 우리는 먼저 트리에서이 색인에 해당하는 노드를 검색해야합니다. 현재 노드의 오른쪽 자손을 포함하여 현재 노드의 모든 조상의 즉각적인 오른쪽 자손에 대한 모든 카운터를 합산해야하지만, 현재 노드가 일부 조상의 오른쪽에있는 모든 경우를 제외해야합니다. 내가 제대로 우리는 우리가 NpowerM을 가질 수 있습니다 알고

우리는 (어떤 교차로가없는 설정 찾을 수 있다면 두 세트 의 관계 (이 값이 X하자) 질문을 이해 한 경우

+3

흠 ... 멋진데 .. 멋지다! 정렬 후이 문제는 병합 정렬로 해결할 수있는 역변환 문제의 수로 변경됩니다. 멋진 ... 다른 테스트 케이스에 대해 확인합니다. 감사합니다. – dejavu

+0

@AndroidDecoded : 오른쪽, 병합 정렬은 인덱스 트리보다 잘 작동합니다. –

+0

이진 인덱스 트리를 사용하여 문제를 해결할 수있는 방법을 plz 정할 수 있습니까? – dejavu

0

는 우리가 그것을 발견 말할 수 Y) 그러면 우리는 XY로부터 X를 빼서 XY가 수학적으로 질문에 대한 답이 될 것입니다 .. inorder를 찾으려면 반대편에있는 요소를 정렬하고 M을 설정 한 다음 가장 길게 늘어나는 부분 시퀀스 ("http : //en.wikipedia.org/wiki/Longest_increasing_subsequence ")를 O (nm)에서 수행 할 수 있습니다. 만약 당신이 충분히 똑똑하다면 O (NlogM) ... 시간에 그것을 할 수 있습니다. 솔루션에 대한 명확성을 위해 (유사한 문제가 여기에 존재합니다. "http://people.csail.mit.edu/bdean/6.046/dp/"건물 브리지 링크 클릭)

+1

만약 당신의 대답을 올바르게 이해했다면, {(1,3), (2,4), (3,1), (4,2)} 그래프에 실패합니다. –