-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path25.pl
105 lines (93 loc) · 1.96 KB
/
25.pl
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/perl -w
use strict;
no warnings 'portable';
use Data::Dumper;
use feature 'say';
use Clipboard;
use List::Util qw/sum min max reduce any all none notall first product uniq pairs mesh zip shuffle/;
use Math::Cartesian::Product;
use Math::Complex;
use List::PriorityQueue;
use Memoize;
use Term::ANSIColor qw(:constants);
use Storable qw(dclone);
use Math::Utils qw(:utility !log10); # Useful functions
BEGIN {push @INC, "../lib";}
use AOC ':all';
use Grid::Dense;
$AOC::DEBUG_ENABLED=0;
$|=1;
my @A;
my %H;
my %E0;
my $sum=0;
#my $grid = Grid::Dense->read();
while (<>) {
chomp;
my ($a,$x) = split(': ');
for my $b (split(' ',$x)) {
my ($a1,$b1) = sort($a,$b);
push @{$H{$a1}},$b1;
push @{$H{$b1}},$a1;
$E0{"$a1,$b1"}++;
}
}
sub rep {
my $uf = shift;
my $key = shift;
my @found;
while (my $next = $uf->{$key}) {
push @found, $key;
$key=$next;
}
for my $f (@found) {
$uf->{$f} = $key;
}
return $key;
}
sub fastmincut {
my $vcount = shift;
my @E = @_;
my %UF;
while ($vcount > 2) {
my ($v1,$v2) = ('','');
my ($ov1,$ov2);
while ($v1 eq $v2) {
my $r = int(rand(@E));
my $e = $E[$r];
($ov1,$ov2) = split(',', $e);
$v1=rep(\%UF,$ov1);
$v2=rep(\%UF,$ov2);
if ($v1 eq $v2) {
#say "delete $ov1 & $ov2 [map to $v1 = $v2]";
$E[$r]=$E[-1];
pop @E;
}
}
#say scalar(%E)." $v1 & $v2 ($ov1 & $ov2)";
$UF{$v2}=$v1;
$vcount--;
}
return grep {my ($v1,$v2) = split(','); rep(\%UF,$v1) ne rep(\%UF,$v2)} @E;
}
my $i=0;
my @cut;
while (@cut != 3) {
@cut = fastmincut(scalar(%H),keys(%E0));
}
my @open=(split(',',$cut[0]))[0];
for my $e (@cut) {
my ($a,$b) = split(',', $e);
$H{$a} = [grep {$_ ne $b} @{$H{$a}}];
$H{$b} = [grep {$_ ne $a} @{$H{$b}}];
}
my %closed;
while (@open) {
my $x = shift @open;
$closed{$x}++;
for my $y (@{$H{$x}}) {
next if $closed{$y};
push @open,$y;
}
}
out(scalar(%closed)* (%H - %closed));