我想学习如何在不使用任何额外模块的情况下解决perl中的简单图论问题 我可以解释一个简单的问题。
输入格式:
第1行 - 图-N的顶点数。
接下来的N行 - 顶点索引,直接连接到索引为i的顶点。指数从1开始
终点索引(空格)终点索引,找到最长路径。
示例
4
2 3 4
1
1 4
1 3
2 4
解决方案:
2 to 4 can be reached in following ways
- 2-1-4
- 2-1-3-4
so longest path is 2-1-3-4
我想学习使用perl解决此类问题的基础知识。任何帮助将受到高度赞赏。给我一个提示,我会尝试编码。
答案 0 :(得分:3)
我使用散列哈希来表示图形。如果边缘$graph{$v1}{$v2}
位于图表中,则v1-v2
存在。您可以通过这种方式表示有向图(因为$graph{$v2}{$v1}
不必存在)。此外,如果您想要加权边,您可以将权重存储为值。
要解决您的示例问题,请使用以下内容:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
# Check that vertex can be added to the path.
sub already {
my ($vertex, @vertices) = @_;
for my $i (1 .. $#vertices) {
# last-v or v-last might already be present.
return 1 if ($vertices[ $i - 1 ] == $vertices[-1] and $vertices[$i] == $vertex)
or ($vertices[ $i - 1 ] == $vertex and $vertices[$i] == $vertices[-1])
}
return
}
sub path {
my ($graph, $start, $end, %known) = @_;
my $count = keys %known;
for my $path (keys %known) {
my @vertices = split '-', $path;
next if $vertices[-1] == $end;
for my $target (keys %{ $graph->{ $vertices[-1] } }) {
undef $known{"$path-$target"} unless already($target, @vertices);
}
}
if (keys %known > $count) {
return path($graph, $start, $end, %known)
} else {
return keys %known
}
}
my %graph;
my $size = <>;
for my $node (1 .. $size) {
my @targets = split ' ', <>;
undef $graph{$node}{$_} for @targets;
}
my ($start, $end) = split ' ', <>;
say "$start to $end can be reached in the following ways";
my @paths = grep /-$end$/,
path(\%graph, $start, $end, map {; "$start-$_" => undef }
keys %{ $graph{$start} });
say for @paths;
my $max = 0;
for my $i (1 .. $#paths) {
$max = $i if ($paths[$i] =~ tr/-//) > ($paths[$max] =~ tr/-//);
}
say "so longest path is $paths[$max]";