-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathA73.php
More file actions
57 lines (47 loc) · 1.46 KB
/
A73.php
File metadata and controls
57 lines (47 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
fscanf(STDIN, "%d %d", $N, $M);
// グラフ構築
$graph = array_fill(0, $N + 1, []);
for ($i = 0; $i < $M; $i++) {
fscanf(STDIN, "%d %d %d %d", $a, $b, $c, $d);
$graph[$a][] = [$b, $c, $d]; // [to, cost, tree]
$graph[$b][] = [$a, $c, $d];
}
// 最短距離・木の数
$dist = array_fill(0, $N + 1, INF);
$trees = array_fill(0, $N + 1, -INF);
$dist[1] = 0;
$trees[1] = 0;
// 優先度付きキュー(SplPriorityQueue 使用)
class PQ extends SplPriorityQueue
{
public function compare($a, $b): int
{
// 辞書順:(距離が小) → (木が多)
if ($a[0] === $b[0]) {
return $b[1] <=> $a[1]; // 木の数多い方が優先
}
return $b[0] <=> $a[0]; // 距離小さい方が優先
}
}
$pq = new PQ();
$pq->insert([0, 0, 1], [0, 0]); // [距離, -木の数, ノード], 優先度
while (!$pq->isEmpty()) {
[$cost, $negTree, $u] = $pq->extract();
$tree = -$negTree;
if ($cost > $dist[$u]) continue;
if ($cost === $dist[$u] && $tree < $trees[$u]) continue;
foreach ($graph[$u] as [$v, $c, $t]) {
$newCost = $cost + $c;
$newTree = $tree + $t;
if (
$newCost < $dist[$v] ||
($newCost === $dist[$v] && $newTree > $trees[$v])
) {
$dist[$v] = $newCost;
$trees[$v] = $newTree;
$pq->insert([$newCost, -$newTree, $v], [$newCost, -$newTree]);
}
}
}
echo $dist[$N] . " " . $trees[$N] . "\n";