結果
| 問題 |
No.17 2つの地点に泊まりたい
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-05-07 18:56:45 |
| 言語 | Fortran (gFortran 14.2.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 2,631 bytes |
| コンパイル時間 | 1,578 ms |
| コンパイル使用メモリ | 35,504 KB |
| 実行使用メモリ | 5,248 KB |
| 最終ジャッジ日時 | 2024-10-15 01:34:28 |
| 合計ジャッジ時間 | 2,422 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 27 |
ソースコード
!>
!! @brief Floyd-Warshallのアルゴリズムを扱います
!! @date 2016/05/07
!!
!!**********************************************************************
!! Floyd-Warshallモジュール(モジュールにする必要はないのかもしれないが。。)
!!**********************************************************************
module module_floyd_warshall
implicit none
public :: floyd_warshall
integer, parameter, public :: inf = 12345678
contains
!>
!! @brief 全点対最短経路問題をFloyd-Warshallのアルゴリズムで解きます
!! @param[in] integer W(:,:) 隣接行列W(ただしW(i,i) = 0であり、i~p~>jを満たす道pが存在しなければW(i,j)=inf)
!! @return 最短路重みの格納した行列D
!!
function floyd_warshall(W)
implicit none
integer, intent(in) :: W(:,:)
integer, allocatable :: floyd_warshall(:,:)
integer :: i, j, k, n
n = size(W, 1)
allocate(floyd_warshall(n, n)) ! ポインタでなければdeallocateする必要はないらしい
floyd_warshall = W ! Wに対して、破壊的代入を行ってもまあいいとおもう
do k = 1, n
do i = 1, n
do j = 1, n
! 任意の整数a!=infに対してa+inf=inf+a=infを仮定しているのでこれはパス
if ((floyd_warshall(i, k) .eq. inf) .or. (floyd_warshall(k, j) .eq. inf)) cycle
floyd_warshall(i, j) = min(floyd_warshall(i, j), (floyd_warshall(i, k) + floyd_warshall(k, j)))
end do
end do
end do
end function floyd_warshall
end module module_floyd_warshall
!!**********************************************************************
!! main program
!!**********************************************************************
program main
use module_floyd_warshall
implicit none
integer :: i, j, k, n, m, e, t
integer, allocatable :: W(:,:), D(:, :), C(:)
integer :: answer
read(*,*) n
allocate(W(n, n), D(n, n), C(n))
do i = 1, n
read(*, *) C(i)
do j = 1, n
W(i, j) = inf !すべての要素をinfで初期化
end do
W(i, i) = 0 ! 対角成分は必ず0
end do
read(*, *) m
do k = 1, m
read(*, *) i, j, e
W(i+1, j+1) = e ! 1-based
W(j+1, i+1) = e ! 無向グラフなので対称性がある
end do
D = floyd_warshall(W)
answer = inf
do i = 2, n - 1
do j = 2, n - 1
if (i .eq. j) cycle
t = D(1, i) + D(i, j) + D(j, n) + C(i) + C(j)
answer = min(answer, t)
end do
end do
write(*, '(I0)') answer
end program main