sub reachable { my ($links, $start, $dest) = @_; return 1 if $start eq $dest; foreach (keys %{ $links->{$start} }) { return 1 if reachable($links, $_, $dest); } return 0; } my %next; my %prev; my $ptr; while() { chomp; if ($_ eq 'Start') { undef $ptr; next; } if (defined $ptr) { if (! $next{$ptr}{$_}) { for my $parent (keys %{ $prev{$_} }) { if (reachable(\%prev, $ptr, $parent)) { delete $prev{$_}{$parent}; } } for my $child (keys %{ $next{$_} }) { if (reachable(\%next, $ptr, $child)) { delete $next{$_}{$child}; } } $next{$ptr}{$_} = 1; $prev{$_}{$ptr} = 1; } } $ptr = $_; }