結果
| 問題 |
No.1 道のショートカット
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-01-13 23:27:27 |
| 言語 | Perl (5.40.0) |
| 結果 |
MLE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 2,916 bytes |
| コンパイル時間 | 54 ms |
| コンパイル使用メモリ | 7,296 KB |
| 実行使用メモリ | 671,232 KB |
| 最終ジャッジ日時 | 2024-07-08 03:40:52 |
| 合計ジャッジ時間 | 9,106 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 19 MLE * 1 -- * 20 |
コンパイルメッセージ
Main.pl syntax OK
ソースコード
# http://yukicoder.me/problems/17
use strict;
use warnings;
use 5.010;
use Data::Dumper;
my $goal = _read_line();
my $money = _read_line();
my $roads = _read_line();
my $map = read_map();
# 前処理終了。
# 解く
my $ans = solve($map, $money, $goal);
say $ans;
sub _read_line {
my $line = <STDIN>;
chomp($line);
return $line;
}
sub read_map {
my $s = [split(/ /, _read_line())];
my $t = [split(/ /, _read_line())];
my $y = [split(/ /, _read_line())];
my $m = [split(/ /, _read_line())];
my $ret = {};
## これ同じ街間に別経路が存在する場合があるみたい。
## なので、コストと距離は配列で持つ。
for (my $i = 0 ; $i < @$s ; $i++) {
my $start = $s->[$i];
my $dest = $t->[$i];
$ret->{$start} ||= {};
$ret->{$start}->{$dest} ||= [];
## 入れたいものよりコストが安く、かつ短い物があるならば無視する
my $skip = 0;
for my $e (@{$ret->{ $start }->{ $dest }}) {
if ($e->{ cost } < $y->[$i] and $e->{ dist } < $m->[$i]) {
$skip = 1;
last;
}
}
next if $skip;
push @{ $ret->{$start}->{$dest} }, {
cost => $y->[$i],
dist => $m->[$i],
};
}
return $ret;
}
sub solve {
my ($map, $money, $goal) = @_;
#die Dumper($map);
my $cur = [
{
pos => 1,
cost => 0,
dist => 0,
}
];
my $res = [];
while (my $state = pop(@$cur)) {
while (my ($k, $v_array) = each(%{$map->{ $state->{ pos } }})) {
for my $v (@$v_array) {
my $cost = $v->{ cost } + $state->{ cost };
my $dist = $v->{ dist } + $state->{ dist };
next if ($cost > $money);
if ($k == $goal) {
push @$res, {
cost => $cost,
dist => $dist,
};
next;
}
## 同じ位置で、コストも安く、距離も短いものがあるならば、入れない
if (has_reasonable($cur, $k, $cost, $dist)) {
next;
}
push @$cur, {
pos => $k,
cost => $cost,
dist => $dist,
};
}
}
}
$res = [sort {$a->{dist} <=> $b->{dist}} @$res];
return -1 if @$res == 0;
return $res->[0]->{dist};
}
sub has_reasonable {
my ($cur, $k, $cost, $dist) = @_;
for my $e (@$cur) {
next if $e->{ pos } != $k;
return 1 if ($e->{ cost } < $cost and $e->{ dist } < $dist);
}
}