線形時間でスーパースターを見つける方法は?


28

有向グラフを検討してください。ノードから他のノードに到達できないが、他のすべてのノードにへのエッジがある場合にのみ、ノードスーパースターを呼び出します。正式に:vv v

v superstar :⟺outdeg(v)=0indeg(v)=n1

グラフ内のノードの数。たとえば、下のグラフでは、塗りつぶされていないノードはスーパースターです(他のノードはそうではありません)。n

スーパースター
[ ソース ]

時間で有向グラフのすべてのスーパースターをどのように識別できますか?適切なグラフ表現は、通常の候補から選択できます。問題の複雑さを前処理に移す表現の使用は控えてください。O(n)

密度に関する仮定はできません。グラフにスーパースターが含まれているとは想定していません。存在しない場合、アルゴリズムはそれを認識する必要があります。

表記法:はノードの発信エッジの数であり、は着信エッジでも同様です。、I 、N 、D 、E 、Goutdegindeg


1
がエッジであるを許可していますか、または各頂点のエッジのみを見る必要がありますか?k O 1 O(n+k)kO(1)
ケビン

@Kevinいいえ、は厳密な要件です。2番目の質問については、それが必要かどうかはわかりませんが、それ以上のことはできません。O(n)
ラファエル

あなたは答えを知っていますか?それがで行うことができます?O(n)
デイブクラーク

@DaveClarke:はい、そしてはい。
ラファエル

表現をさらに制限する必要があります。隣接リストでは線形アルゴリズムは不可能です(頂点がスーパースターであることを確認するために、各頂点でリスト全体を調べる必要がある場合があります)。
ジル「SO-悪であるのをやめる」

回答:


18

チェックする各エッジごとに1つの可能性を排除できるため、エッジの存在をチェックすることで、頂点の1つを除くすべてを削除できます。行くエッジがある場合、特に、と、我々は排除上へと移動し(別の頂点がそこから到達できるように)。そうでない場合、を削除します(から到達できないため)。最後の頂点に到達したら、削除されない頂点は、削除されるか、スーパースターとして確認されるまで、他の頂点と比較する必要があります(スーパースター条件が維持されていることを確認してください。いくつかの擬似コード:x y x y y xn1xyxyyx

vertex superstar(graph g)
    current vertex = first
    # Go through each vertex
    for each subsequent vertex in g ("next")
        # If there's an edge from this to the next, we eliminate this one [move to the new one].
        # If not, we just stay here.
        if edge exists from current to next
            candidate = next
        end if
    end for
    # Now we are on the final remaining candidate, check whether it satisfies the requirements.
    # just a rename for clarity
    candidate = current
    for each other vertex in g
        if edge from current to other exists
            return null 
        else if no edge from other to current
            return null
        end if
    end for
    return candidate
end superstar

メソッドを説明するために例を見ていきましょう。ソースの頂点が上部にあり、デスティネーションが側面にあるこの配列を使用します。1はエッジを示します。

12341101210131114110

潜在的なスーパースターとして除外した頂点をグレーアウトします。緑と赤を使用して、探しているエッジが含まれている場合と含まれていない場合に見ているエッジを示し、青は既に見た場所を示します。

まず、頂点1と2を調べます。

12341101210131114110
緑色の数字は2から1のエッジがあることを示しているため、2を削除してエッジを探します3から1:

12341101210131114110

そのようなエッジがないことがわかるので、1を削除し、現在の頂点として3を取ります。既に2を削除していることを思い出してください。4から3のエッジがあるかどうかを確認してください。

12341101210131114110

4から3までのエッジがあるため、4を削除します。この時点で、頂点(3)の1つを除くすべてを削除したので、エッジをチェックして、条件を満たすかどうかを確認します。

12341101210131114110

1から3までのエッジがありますが、その逆はないため、3は依然として候補です。

12341101210131114110

2から3までのエッジもありますが、その逆はないため、3は依然として候補です。

12341101210131114110

4〜3のエッジがありますが、3〜4のエッジはありません。これで3のエッジのチェックが完了し、実際にスーパースターであることがわかりました。

最初のエッジチェックのそれぞれでスーパースターとして1つの頂点を削除するため 、最良のケースは番目のチェックで複雑さの最終頂点を削除することです。最悪の場合(最後または最後から2番目の頂点がスーパースターであるか、最終チェックでそれが不適格となる)、最初の比較の後に、候補を個の頂点と比較します。最悪の場合の複雑さ()。したがって、このアルゴリズムは です。n1nnn12×(n1)3n3O(n)Θ(n)


8

これは有名人の問題ではありませんか?

スーパースター(有名人)がいる場合は、1人だけです。

隣接行列表現を使用します。ここで、からへの有向エッジがある場合は、そうでない場合はです。(私はそれが許可されていると推測しています)。A[i,j]=1ij0

(時間で実行可能)を調べることで、そのうちの少なくとも1つを有名人の候補として削除できます場合、その後、を削除できます。場合、我々は排除することができます。A[i,j]O(1)A[i,j]=1iA[i,j]=0j

現在の候補者のリストを維持し、1つずつ削除します。リンクされたリストで十分です。

最後に、候補者が本当にスーパースターであるかどうかを確認できます。

このアルゴリズムはます。O(n)


一定の時間で適切なをどのように選択しますか?(i,j)
ラファエル

3
@Raphael:リンクされたリストから最初の2つの候補を選択するだけです。(頭と頭->次)。
アリヤバタ

6

この回答は、質問の現在のバージョンではなく、グラフ表現が可能な質問のバージョンに対応しています。

  • グラフを隣接リストと逆隣接リストのペアとして保存します。各リストにはリストの長さが追加されているため、それぞれアウトエッジとインエッジの数が含まれます。

  • 前処理:逆隣接リスト(つまり、インエッジのリスト)を計算します。コストO(|E|)

  • 0n1O(|N|)


わかりましたグラフ表現を許可するのは弱すぎると思います。質問を意図したものに限定しました。
ラファエル

2

参考までに、これはKevinが投稿したものの再帰バージョンの擬似コードです。

superstar(V, E) {
  if ( |V| == 1 ) {
    return V.pop
  }

  a = V.pop
  b = V.pop
  if ( (a,b) ∈ E ) {
    no_ss = a
    keep  = b
  }
  else {
    no_ss = b
    keep = a
  }

  s = superstar(V ++ keep)

  return ( s != null && (no_ss, s) ∈ E && !(s, no_ss) ∈ E ) ? s : null
}

hasSuperstar(V, E) = superstar(V, E) != null
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.