// File: /workspace/github_cpp_makefile_star2_O1/canzarlab[P]Trajan/src/match.cpp
// Function: main
int main(int argc, char** argv)
{
    if (argc != 6)
    {
        cout << "usage: " << argv[0] << " <tree1> <map1> <tree2> <map2> <matrix>\n";
        return 0;
    }
    // load the data
    tree t1(argv[1], argv[2]);
    tree t2(argv[3], argv[4]);
    vector<vector<double>> cost_matrix = CSVReader(argv[5]).getDoubleData();

    // last row/column is deletion cost
    array2d minmatrix(t1.n + 1, t2.n + 1);

    // convert scores to integers
    const double scale = 1000;
    for (int i = 0; i < t1.n + 1; ++i)
        for (int j = 0; j < t2.n + 1; ++j)
            minmatrix(i, j) = scale * cost_matrix[i][j];

    // convert into maximization problem
    array2d maxmatrix(t1.n, t2.n);
    for (int i = 0; i < t1.n; ++i)
        for (int j = 0; j < t2.n; ++j)
            maxmatrix(i, j) = minmatrix(i, t2.n) + minmatrix(t1.n, j) - minmatrix(i, j);

    // minimization score of empty matching
    int null_score = 0;
    for (int i = 0; i < t1.n; ++i)
        null_score += minmatrix(i, t2.n);
    for (int i = 0; i < t2.n; ++i)
        null_score += minmatrix(t1.n, i);

    // compute optimal tree to tree matching
    // note: first node in topological ordering is the root
    int weight = forest_forest(t1, t2, maxmatrix, 1, 1);

    // recover the matching
    vector<pair<int, int>> matching;
    recover_matching(t1, t2, matching, 1, 1);

    // weight of recovered matching (for sanity check)
    int mweight = 0;
    for (auto [x, y] : matching)
        mweight += maxmatrix(x, y);

    // convert to minimization score
    weight = null_score - weight;
    mweight = null_score - mweight;

    // verify the matching
    assert(verify(t1, t2, matching));
    assert(weight == mweight);

    // scale back the score
    clog << weight / scale << endl;

    // print the matching
    for (auto [x, y] : matching)
        cout << t1.rm[x] << ' ' << t2.rm[y] << '\n';
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10798, %rsp          # imm = 0x10798
movq %rsi, %rbx
cmpl $0x6, %edi
jne 0x537c
movq 0x8(%rbx), %rsi
movq 0x10(%rbx), %rdx
leaq 0x8440(%rsp), %rdi
callq 0x5b0c
movq 0x18(%rbx), %rsi
movq 0x20(%rbx), %rdx
leaq 0xe8(%rsp), %rdi
callq 0x5b0c
movq 0x28(%rbx), %rsi
leaq 0xb0(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6350
leaq 0xa0(%rsp), %r14
movq %r14, -0x10(%r14)
leaq 0x5f1e(%rip), %rsi      # 0xb069
leaq 0x5f18(%rip), %rdx      # 0xb06a
leaq 0x90(%rsp), %rdi
callq 0x7176
leaq 0x50(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0x90(%rsp), %rdx
callq 0x638e
leaq 0xd0(%rsp), %rdi
leaq 0x50(%rsp), %rsi
xorl %edx, %edx
movl $0x2710, %ecx           # imm = 0x2710
callq 0x83b0
leaq 0x80(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x51b3
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x3230
leaq 0x60(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x51ce
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x3230
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x51eb
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3230
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x520c
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3230
movl 0xe248(%rsp), %esi
incl %esi
movl 0x5ef0(%rsp), %edx
incl %edx
leaq 0x50(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x5864
movl 0xe248(%rsp), %esi
testl %esi, %esi
js 0x52ae
movq 0xd0(%rsp), %rax
movq 0x58(%rsp), %rcx
xorl %edx, %edx
movsd 0x5db9(%rip), %xmm0     # 0xb008
cmpl $0x0, 0x5ef0(%rsp)
js 0x529a
leaq (%rdx,%rdx,2), %rsi
movq (%rax,%rsi,8), %rsi
movslq %edx, %rdi
xorl %r8d, %r8d
movsd (%rsi,%r8,8), %xmm1
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %r9d
movslq 0x54(%rsp), %r10
imulq %rdi, %r10
addq %r8, %r10
movl %r9d, (%rcx,%r10,4)
leaq 0x1(%r8), %r9
movslq 0x5ef0(%rsp), %r10
cmpq %r10, %r8
movq %r9, %r8
jl 0x5267
leaq 0x1(%rdx), %rdi
movslq 0xe248(%rsp), %rsi
cmpq %rsi, %rdx
movq %rdi, %rdx
jl 0x524f
movl 0x5ef0(%rsp), %edx
leaq 0x30(%rsp), %rdi
movl $0x80000000, %ecx       # imm = 0x80000000
callq 0x5864
movl 0xe248(%rsp), %esi
testl %esi, %esi
jle 0x534a
movq 0x58(%rsp), %rax
xorl %ecx, %ecx
movq 0x38(%rsp), %rdx
movl 0x5ef0(%rsp), %r8d
testl %r8d, %r8d
jle 0x533d
movslq %ecx, %rsi
xorl %edi, %edi
movslq 0x54(%rsp), %r9
movslq 0xe248(%rsp), %r10
imulq %r9, %r10
imull %ecx, %r9d
addl %r9d, %r8d
movslq %r8d, %r8
addq %rdi, %r10
movl (%rax,%r10,4), %r10d
addl (%rax,%r8,4), %r10d
movslq %r9d, %r8
addq %rdi, %r8
subl (%rax,%r8,4), %r10d
movslq 0x34(%rsp), %r8
imulq %rsi, %r8
addq %rdi, %r8
movl %r10d, (%rdx,%r8,4)
movl 0x5ef0(%rsp), %r8d
incq %rdi
cmpl %r8d, %edi
jl 0x52ed
incl %ecx
movl 0xe248(%rsp), %esi
cmpl %esi, %ecx
jl 0x52db
testl %esi, %esi
jle 0x53f0
movslq 0x5ef0(%rsp), %rax
movslq 0x54(%rsp), %rcx
movl %esi, %edx
shlq $0x2, %rax
addq 0x58(%rsp), %rax
shlq $0x2, %rcx
xorl %ebp, %ebp
addl (%rax), %ebp
addq %rcx, %rax
decq %rdx
jne 0x5370
jmp 0x53f2
movq 0xac4d(%rip), %r14      # 0xffd0
leaq 0x5cae(%rip), %rsi      # 0xb038
movl $0x7, %edx
movq %r14, %rdi
callq 0x3270
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x53bb
movq %rbx, %rdi
callq 0x3100
movq 0xac22(%rip), %rdi      # 0xffd0
movq %rbx, %rsi
movq %rax, %rdx
callq 0x3270
jmp 0x53d3
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x33b0
movq 0xabf6(%rip), %rdi      # 0xffd0
leaq 0x5c5f(%rip), %rsi      # 0xb040
movl $0x28, %edx
callq 0x3270
jmp 0x56a4
xorl %ebp, %ebp
movslq 0x5ef0(%rsp), %rax
testq %rax, %rax
jle 0x5421
movslq 0x54(%rsp), %rdx
movslq %esi, %rcx
imulq %rdx, %rcx
shlq $0x2, %rcx
addq 0x58(%rsp), %rcx
xorl %edx, %edx
addl (%rcx,%rdx,4), %ebp
incq %rdx
cmpq %rdx, %rax
jne 0x5416
leaq 0x8440(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movl $0x1, %ecx
movl $0x1, %r8d
callq 0x3d62
movl %eax, %ebx
xorpd %xmm0, %xmm0
leaq 0x10(%rsp), %rdx
movapd %xmm0, (%rdx)
movq $0x0, 0x10(%rdx)
leaq 0x8440(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
movl $0x1, %ecx
movl $0x1, %r8d
callq 0x4946
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
cmpq %rcx, %rax
je 0x54bb
movl 0x34(%rsp), %edx
xorl %r14d, %r14d
movq 0x38(%rsp), %rsi
movq (%rax), %rdi
movl %edx, %r8d
imull %edi, %r8d
shrq $0x20, %rdi
addl %edi, %r8d
movslq %r8d, %rdi
addl (%rsi,%rdi,4), %r14d
addq $0x8, %rax
cmpq %rcx, %rax
jne 0x5498
jmp 0x54be
xorl %r14d, %r14d
leaq 0x8440(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x4d5a
testb %al, %al
je 0x56b8
cmpl %ebx, %r14d
jne 0x56d7
subl %ebx, %ebp
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
divsd 0x5b0e(%rip), %xmm0     # 0xb008
movq 0xaaa7(%rip), %rdi      # 0xffa8
callq 0x3340
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3210
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3190
movq 0x10(%rsp), %r15
movq 0x18(%rsp), %r12
cmpq %r12, %r15
je 0x55c6
movq 0xaa86(%rip), %rbx      # 0xffd0
leaq 0xf(%rsp), %r14
movq (%r15), %r13
movq 0x8470(%rsp), %rax
movslq %r13d, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rsi
movq 0x8(%rax,%rcx), %rdx
movq %rbx, %rdi
callq 0x3270
movb $0x20, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3270
sarq $0x20, %r13
movq 0x118(%rsp), %rcx
shlq $0x5, %r13
movq (%rcx,%r13), %rsi
movq 0x8(%rcx,%r13), %rdx
movq %rax, %rdi
callq 0x3270
movb $0xa, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x3270
addq $0x8, %r15
cmpq %r12, %r15
jne 0x554f
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x55dd
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x55f4
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x560b
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
leaq 0xd0(%rsp), %rdi
callq 0x6428
movl $0x5e00, %ebx           # imm = 0x5E00
movq 0xd8(%rsp,%rbx), %rdi
testq %rdi, %rdi
je 0x563a
movq 0xe8(%rsp,%rbx), %rsi
subq %rdi, %rsi
callq 0x3230
addq $-0x18, %rbx
cmpq $0x40, %rbx
jne 0x561d
leaq 0x118(%rsp), %rdi
callq 0x6866
leaq 0xe8(%rsp), %rdi
callq 0x7128
movl $0x5e00, %ebx           # imm = 0x5E00
movq 0x8430(%rsp,%rbx), %rdi
testq %rdi, %rdi
je 0x5680
movq 0x8440(%rsp,%rbx), %rsi
subq %rdi, %rsi
callq 0x3230
addq $-0x18, %rbx
cmpq $0x40, %rbx
jne 0x5663
leaq 0x8470(%rsp), %rdi
callq 0x6866
leaq 0x8440(%rsp), %rdi
callq 0x7128
xorl %eax, %eax
addq $0x10798, %rsp          # imm = 0x10798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x59ac(%rip), %rdi      # 0xb06b
leaq 0x59be(%rip), %rsi      # 0xb084
leaq 0x59c5(%rip), %rcx      # 0xb092
movl $0x2c8, %edx            # imm = 0x2C8
callq 0x3180
leaq 0x59cb(%rip), %rdi      # 0xb0a9
leaq 0x599f(%rip), %rsi      # 0xb084
leaq 0x59a6(%rip), %rcx      # 0xb092
movl $0x2c9, %edx            # imm = 0x2C9
callq 0x3180
jmp 0x5773
movq %rax, %rbx
jmp 0x578d
movq %rax, %rbx
jmp 0x57a4
movq %rax, %rbx
jmp 0x57bb
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x63f2
jmp 0x5722
movq %rax, %rbx
movq 0x90(%rsp), %rdi
cmpq %r14, %rdi
je 0x5744
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x3230
jmp 0x5744
movq %rax, %rbx
leaq 0xc0(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x57c8
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x3230
jmp 0x57c8
movq %rax, %rbx
jmp 0x57c8
movq %rax, %rbx
jmp 0x57d5
jmp 0x5773
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x578d
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x57a4
movq 0x48(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x57bb
movq 0x68(%rsp), %rsi
subq %rdi, %rsi
callq 0x3230
leaq 0xd0(%rsp), %rdi
callq 0x6428
leaq 0xe8(%rsp), %rdi
callq 0x6476
leaq 0x8440(%rsp), %rdi
callq 0x6476
movq %rbx, %rdi
callq 0x33e0