[伯俊]空港:Union-Find
6978 ワード
質問する
http://boj.kr/10775
概要
問題の目立つ文は
すなわち、iii便目を1日からのg igig i(1≦g igig i≦G)の1番目の関門の1つに永久的に停泊しようとし、飛行機がいずれの関門にも停泊できない場合、空港は閉鎖され、その後どの便も到着できない.
すなわち、iii機ごとにg igig i値が入力され、入力値以下の番号のゲートのみが接続される.
また、ドッキング可能な最大飛行機数を得る必要があります.
問題を解く
質問を読んで、ちょっと見るとO(GP)O(GP)O(GP)の答えが思い浮かぶ.
ドッキングを最大限に行うには,まず,与えられたg igig iに直接対応できるかどうかを判断し,できれば直接ドッキングできる.
直接ドッキングできない場合は、g i 1 gi-1 g i1に相当するゲートが接続されます.
つまり、関門を1つ減らすたびに、飛行機が関門に止まっているかどうかを確認するという大きな問題です.
線形計算では,最悪の場合,ゲートウェイごとにすべてのゲートウェイがチェックされるため,時間的複雑さはO(GP)O(GP)O(GP)O(GP)となる.
でもこのまま解くとTLEは当然爆発します.(範囲が非常に広い)
だから私が考えられる他のアイデアは
g igig iを入力すると、すぐにgigig以下の番号のゲートからドッキング可能なゲートを見つけることができますが、どうなりますか?から出発する.
すぐにはわからなくても、最大限圧縮して、gigig iより小さいゲートに空っぽの情報を伝えたいなら、gig iゲートに停泊して、可能なゲート更新のアイデアをあげましょう.
すなわち,最初に自分を指す状態から他のノードを指す状態に変更する必要がある.
これはUnionFindアルゴリズムによって解決できる.
空港レイアウトの最初のインデックスはi-1を値とします.(airport[i]=i-1)
これは、g igig iが入力され、g igig i上でドッキングできない場合に、g ii-1 g i1のゲートウェイをドッキングしようとすると理解できる.
次の手順は次のとおりです.
コード#コード#
import sys
sys.setrecursionlimit(10**5)
In = lambda : sys.stdin.readline().rstrip()
MIS = lambda : map(int, In().split())
def find(x):
if x<=0:
return -1
if not vist[x]:
vist[x]=1
return airport[x]
airport[x] = find(airport[x])
return airport[x]
G = int(In())
P = int(In())
airport = [i-1 for i in range(G+1)]
vist = [0]*(G+1)
ans=0
for p in range(P):
g=int(In())
fg=find(g)
if fg==-1:
print(ans)
sys.exit(0)
break
ans+=1
print(ans)
Reference
この問題について([伯俊]空港:Union-Find), 我々は、より多くの情報をここで見つけました https://velog.io/@seilk/백준-공항-Union-Findテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol