[python]伯俊11265終わらないパーティー(Floyd-Warshall)
17214 ワード
📌 質問する
パーティー好きのミンホは、パーティーが続く遊園地「ミンホワールド」を作った.最初はパーティー会場が1つしかない小さな遊園地だったが、ますます多くの人がパーティー会場を拡張し、現在はNつのパーティー会場を持つ大きな遊園地となっている.民浩はパーティー会場を拡張するたびに、便宜上、新しいパーティー会場と既存のすべてのパーティー会場を直接接続できる道路を建設する.このとき建設された道路は利用者を便利にするために一方通行に設計されている.
キャプテンが少ない時は悪くなかったが、キャプテンが多くなり、現在は以下の2つの問題が発生している.
入力
入力された最初の行は、キャプテンのサイズN(5≦N≦500)と、サービスを要求する顧客の数M(1≦M≦10000)を与える.各宴会場には1番からN番まで番号がついています.次はN行で、各行にはN個の数があります.i列のj回数T(1≦T≦1000000)とは、i列から直接j列に接続された道路を移動する時間を指す.
次のM行は3つの整数A,B,Cを与える.A(1≦A≦N)は招待サービスの客がいる宴会場番号、B(1≦B≦N)は次の宴会場番号、C(1≦C≦10000000)はこれから次の宴会を開くのに要する時間を示す.
しゅつりょく
M行にまたがるサービスを要請した客が時間内に別の宴会場に到着できる場合は「Enjoy other party」を出力し、時間内に到着できない場合は「Stay here」を出力する.
入力例1
5 10
0 4 4 8 7
7 0 7 7 4
1 4 0 5 4
5 2 2 0 7
1 4 1 6 0
1 3 8
2 4 1
4 1 1
1 5 5
3 2 1
3 2 5
4 5 10
5 3 2
1 4 1
1 4 11
サンプル出力1
Enjoy other party
Stay here
Stay here
Stay here
Stay here
Enjoy other party
Enjoy other party
Enjoy other party
Stay here
Enjoy other party
📌 に答える
💬 Code
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
for k in range(n):
for i in range(n):
for j in range(n):
if graph[i][j] > graph[i][k] + graph[k][j]:
graph[i][j] = graph[i][k] + graph[k][j]
for _ in range(m):
a, b, time = map(int, input().split())
if graph[a-1][b-1] <= time:
print('Enjoy other party')
else:
print('Stay here')
💡 Solution
A 파티장에서 B 파티장으로 빨리 갈 수 있도록
직접 연결이 된 일방통행 도로를 만들었지만
A와 B가 아닌 다른 파티장을 경유해서
더 빨리 갈 수 있는 경우가 있을 수 있다.
上記の条件により,この問題は最短経路問題に相当し,すべてのノードの最短経路を計算する必要があるためfloydwalshアルゴリズムを採用した.for k in range(n):
for i in range(n):
for j in range(n):
if graph[i][j] > graph[i][k] + graph[k][j]:
graph[i][j] = graph[i][k] + graph[k][j]
iパーティー場からjパーティー場に向かう場合、kパーティー場を経由する方が早いと最短経路で更新できます.for _ in range(m):
a, b, time = map(int, input().split())
if graph[a-1][b-1] <= time:
print('Enjoy other party')
else:
print('Stay here')
問題ではキャプテンの番号を1からnと指定しているので、図にアクセスする際にはインデックスから1を減算した場合にアクセスする必要があります.🤔 タイムアウトの問題
最高値をminに更新
for k in range(n):
for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])
ifゲートで最高値を更新
for k in range(n):
for i in range(n):
for j in range(n):
if graph[i][j] > graph[i][k] + graph[k][j]:
graph[i][j] = graph[i][k] + graph[k][j]
min()を使用すると、graph[i][j]、graph[i][k]+graph[k][j]を毎回比較し、graph[i][j]の操作に割り当てる.したがってgraph[i][j]をgraph[i][j]に割り当てることが頻繁に発生する.逆に、文が条件を満たしていない場合は、文は割り当てられないため、不要な割り当て操作は発生しません.
for i in range(n) ❌
for i in range(m):
a, b, time = map(int, input().split())
for _ in range(n) ⭕
for _ in range(m):
a, b, time = map(int, input().split())
for文では,変数iを用いることがなければ,変数を指定しない習慣を身につける.これがタイムアウトになるとは思わなかったのですが・・・pypy 3で採点すれば両方とも❌で採点してもタイムアウト判定なしで正解が得られますが、pyth 3で採点すれば両方とも❌で採点して正解が得られます.
floydwalshアルゴリズムはノードが500個未満の場合に適しているが,この問題では最大500個のノードがあり,時間がかなり短い.時間が多すぎると無視できる違いがあるかもしれませんが、500ノードなので3重forゲートの切り替え作業が多すぎるので微妙な違いでタイムアウトするかどうかが決まります^ㅠ
Reference
この問題について([python]伯俊11265終わらないパーティー(Floyd-Warshall)), 我々は、より多くの情報をここで見つけました https://velog.io/@hygge/Python-백준-11265-끝나지-않는-파티-Floyd-Warshallテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol