zombie = [] for k in range(K): zombie.append(int(input())-1)
link = [ [] for _ in range(N)]
for m in range(M): a, b = map(int, input().split()) link[a-1].append(b-1) link[b-1].append(a-1)
dist = [INF] * N q = deque(zombie) for v in zombie: dist[v] = 0 while q: node = q.popleft() for next in link[node]: if dist[next] != INF: # 探索済みの場合はパスされる。、 continue# distは小さい順にqに格納されるので、ゾンビからの最小距離を求めることがd系る dist[next] = dist[node] + 1 q.append(next)
cost = [P] * N for n in range(N): if dist[n] <= S: cost[n] = Q if n in zombie: cost[n] = INF if n==0or n==N-1: cost[n] = 0
defdijkstra(s, g): dists = [INF for i in range(N)] dists[s] = 0 pq = [(0, s)] # 優先度付きキューのオブジェクトそのものはただのリスト while(pq[0][1]!=g): d, node = heapq.heappop(pq) if (d > dists[node]): # 探索の対象にする必要があるか確認 continue for next in link[node]: c = cost[next] if d + c < dists[next]: # 探索の対象にする必要があるか確認 dists[next] = d + c heapq.heappush(pq, (dists[next],next)) return pq[0][0] print (dijkstra(0,N-1))
V, E, r = map(int,input().split()) adj = [[] for i in range(V)] # 隣接リスト
for e in range(E): s, t, d = map(int,input().split()) adj[s].append((t,d))
dists = [INF for i in range(V)] # 重みの和 dists[r] = 0 pq = [(0, r)] # 二分ヒープの実体はリストやタプルとして表現する # (重みの和, ノード番号) while(pq): d, node = heapq.heappop(pq) if (d > dists[node]): # 探索の対象にする必要があるか確認 continue for next, cost in adj[node]: if d + cost < dists[next]:# 探索の対象にする必要があるか確認 dists[next] = d + cost # 次のノードにおける重みの和 heapq.heappush(pq, (dists[next],next)) for d in dists: if d == INF: print ('INF') else: print (d)
defdijkstra(s, g): dists = [INF for i in range(N)] dists[s] = 0 pq = [(0, s)] # 優先度付きキューのオブジェクトそのものはただのリスト while(pq): d, node = heapq.heappop(pq) if (d > dists[node]): # 探索の対象にする必要があるか確認 continue for next, cost in adj[node]: if d + cost < dists[next]: dists[next] = d + cost heapq.heappush(pq, (dists[next],next)) if dists[g] == INF: return-1 else: return dists[g]
N, K = map(int,input().split()) adj = [[] for i in range(N)] ans = [] for k in range(K): ls = list(map(int,input().split())) if ls[0]==0: ans.append(dijkstra(ls[1]-1, ls[2]-1)) else: adj[ls[1]-1].append((ls[2]-1,ls[3])) adj[ls[2]-1].append((ls[1]-1,ls[3])) for a in ans: print (a)
defdijkstra(s, g): dists = [INF for i in range(N)] dists[s] = 0 pq = [(0, s)] # 優先度付きキューのオブジェクトそのものはただのリスト while(pq): d, node = heapq.heappop(pq) if (d > dists[node]): # 探索の対象にする必要があるか確認 continue for next, cost in adj[node]: if d + cost < dists[next]: # 更新すべきか確認 dists[next] = d + cost heapq.heappush(pq, (dists[next],next)) if dists[g] == INF: return-1 else: return dists[g]
N, K = map(int,input().split()) adj = [[] for i in range(N)] ans = [] for k in range(K): ls = list(map(int,input().split())) if ls[0]==0: ans.append(dijkstra(ls[1]-1, ls[2]-1)) else: adj[ls[1]-1].append((ls[2]-1,ls[3])) adj[ls[2]-1].append((ls[1]-1,ls[3])) for a in ans: print (a)
N = int(input()) INF = 10**10 cost = [[INF]*N for _ in range(N)] # INFで初期化v
for u in range(N): C = list(map(int, input().split())) for v in range(N): if u==v: # 自身への道路はINFのままにする continue cost[u][v] = C[v] ans = 0 for u in range(N): for v in range(u+1,N): # u < v mn = INF # u-w-vのような経路の中で最小の距離を求める for w in range(N): mn = min(mn, cost[u][w]+cost[w][v]) if (cost[u][v] > mn): # 与えられた行列が最短経路ではない print (-1) # 終了して良い exit() elif (cost[u][v] < mn): # 等しくない場合はu-vを直接結ぶ道路が必要 ans += cost[u][v] print (ans)
N, M = map(int, input().split()) INF = 10**10 cost = [[INF]*N for _ in range(N)] for n in range(N): cost[n][n] = 0 for m in range(M): a, b, t = map(int, input().split()) cost[a-1][b-1] = t cost[b-1][a-1] = t
for i in range(N): # 中継点 for j in range(N): # 始点 for k in range(N): # 終点 cost[j][k] = min(cost[j][i]+cost[i][k], cost[j][k])
ans = INF for n in range(N): mx = max(cost[n]) if mx < ans: ans = mx print (ans)
import bisect import sys input = sys.stdin.readline N = int(input()) A = [] for n in range(N): A.append(int(input())) A = A[::-1] # 数列の後ろから処理 INF = int(1e+9 + 10) lis = [INF] * N # 初期化 for n in range(N): i = bisect.bisect(lis, A[n]) # 更新すべき最小値 lis[i] = A[n] print (bisect.bisect_left(lis, INF)) # `INF`となっていない色の種類数
N = int(input()) cards = [] for n in range(N): cards.append(int(input())) INF = 10010 lis = [INF] * (N+1) # 列の右端の最小値 lis[0] = 0 ans = 0 for n in range(N): for m in range(n+1): # 無駄にINFの領域を探索する必要はない if lis[m] < cards[n] and cards[n] < lis[m+1]: # 今回は同じ値のカードはない lis[m+1] = cards[n] ans = max(ans, m+1) break# 更新できたらループを抜けて良い print(N-ans)
満点解法
上記のアルゴリズムは計算量がO(n^2)であるが、さらに高速化ができる。
列の右端の最小値が増加列であるということを利用して、二分探索を行えば良い。
コード(100点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import bisect N = int(input()) cards = [] for n in range(N): cards.append(int(input())) INF = 100010 lis = [INF]* (N+1) lis[0] = 0 ans = 0 for n in range(N): i = bisect.bisect(lis, cards[n]) # 二分探索 lis[i] = cards[n] ans = max(ans, i) print(N-ans)