// File: ekg[P]sgd2/src/sgd2.hpp
// Function: sgd2::maxmin_random_sp_unweighted(std::vector<std::vector<unsigned long, std::allocator<unsigned long>>, std::allocator<std::vector<unsigned long, std::allocator<unsigned long>>>> const&, unsigned long, unsigned long)
std::vector<uint64_t> maxmin_random_sp_unweighted(const std::vector<std::vector<uint64_t>>& graph, uint64_t n_pivots, uint64_t p0)
{
    uint64_t n = graph.size();

    std::vector<uint64_t> mins(n, std::numeric_limits<uint64_t>::max());
    std::vector<uint64_t> argmins(n, -1);

    // first pivot
    mins[p0] = 0;
    argmins[p0] = p0;
    maxmin_bfs_unweighted(graph, p0, mins, argmins);
    for (uint64_t i = 0; i < n; i++)
    {
        if (argmins[i] == -1)
            throw "graph is not strongly connected, or is not indexed from zero";
    }

    // remaining pivots
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<> rng(0, 1);
    for (uint64_t i = 1; i < n_pivots; i++)
    {
        // uint64_t max = mins[0], argmax = 0;
        // for (uint64_t i = 1; i < n; i++)
        // {
        //     if (mins[i] > max)
        //     {
        //         max = mins[i];
        //         argmax = i;
        //     }
        // }
        // maxmin non-random above

        // choose pivots with probability min
        uint64_t min_total = 0;
        for (uint64_t i = 0; i < n; i++)
        {
            min_total += mins[i];
        }
        double rn = rng(mt) * min_total;
        uint64_t cumul = 0;
        uint64_t argmax = 0;
        for (uint64_t i = 1; i < n; i++)
        {
            cumul += mins[i];
            if (cumul >= rn)
            {
                argmax = i;
                break;
            }
        }

        mins[argmax] = 0;
        argmins[argmax] = argmax;
        maxmin_bfs_unweighted(graph, argmax, mins, argmins);
    }
    // TODO: look for error in bfs here
    return argmins;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2830, %rsp           # imm = 0x2830
movq %rdi, -0x27f0(%rbp)
movq %rdi, %rax
movq %rax, -0x27e8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0xb050
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x27e0(%rbp)
callq 0xb080
movq %rax, -0x48(%rbp)
leaq -0x49(%rbp), %rdi
movq %rdi, -0x27d8(%rbp)
callq 0x9df0
movq -0x27e0(%rbp), %rsi
movq -0x27d8(%rbp), %rcx
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x9e10
jmp 0x4d3a
leaq -0x49(%rbp), %rdi
callq 0x9e90
movb $0x0, -0x5d(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x2800(%rbp)
movq $-0x1, -0x68(%rbp)
leaq -0x69(%rbp), %rdi
movq %rdi, -0x27f8(%rbp)
callq 0x9df0
movq -0x27f0(%rbp), %rdi
movq -0x2800(%rbp), %rsi
movq -0x27f8(%rbp), %rcx
leaq -0x68(%rbp), %rdx
callq 0x9e10
jmp 0x4d8a
leaq -0x69(%rbp), %rdi
callq 0x9e90
movq -0x20(%rbp), %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0x2808(%rbp)
callq 0x9ee0
movq -0x27f0(%rbp), %rdi
movq $0x0, (%rax)
movq -0x20(%rbp), %rsi
movq %rsi, -0x2810(%rbp)
callq 0x9ee0
movq -0x2810(%rbp), %rsi
movq -0x2808(%rbp), %rdx
movq -0x27f0(%rbp), %rcx
movq %rsi, (%rax)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5170
jmp 0x4dec
movq $0x0, -0x78(%rbp)
movq -0x78(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x4e9c
movq -0x27f0(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x9ee0
cmpq $-0x1, (%rax)
jne 0x4e89
movl $0x8, %edi
callq 0x2080
movq %rax, %rdi
leaq 0x19265(%rip), %rax     # 0x1e091
movq %rax, (%rdi)
movq 0x2918a(%rip), %rsi     # 0x2dfc0
xorl %eax, %eax
movl %eax, %edx
callq 0x2290
jmp 0x5162
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x49(%rbp), %rdi
callq 0x9e90
jmp 0x5159
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x69(%rbp), %rdi
callq 0x9e90
jmp 0x5150
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5144
jmp 0x4e8b
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0x4df4
leaq -0x1400(%rbp), %rdi
callq 0x93e0
jmp 0x4eaa
leaq -0x1400(%rbp), %rdi
callq 0x9480
movl %eax, -0x2814(%rbp)
jmp 0x4ebe
movl -0x2814(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x2788(%rbp), %rdi
callq 0x94a0
jmp 0x4ed6
leaq -0x2798(%rbp), %rdi
xorps %xmm0, %xmm0
movsd 0x19120(%rip), %xmm1    # 0x1e008
callq 0xb090
jmp 0x4eef
movq $0x1, -0x27a0(%rbp)
movq -0x27a0(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x5109
movq $0x0, -0x27a8(%rbp)
movq $0x0, -0x27b0(%rbp)
movq -0x27b0(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x4f80
movq -0x27b0(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x9ee0
movq (%rax), %rax
addq -0x27a8(%rbp), %rax
movq %rax, -0x27a8(%rbp)
movq -0x27b0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x27b0(%rbp)
jmp 0x4f21
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1400(%rbp), %rdi
callq 0x9900
jmp 0x5144
leaq -0x2798(%rbp), %rdi
leaq -0x2788(%rbp), %rsi
callq 0xb0c0
movsd %xmm0, -0x2820(%rbp)
jmp 0x4f9d
movsd -0x2820(%rbp), %xmm0
movaps 0x19094(%rip), %xmm2    # 0x1e040
movq -0x27a8(%rbp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x19090(%rip), %xmm2    # 0x1e050
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x27b8(%rbp)
movq $0x0, -0x27c0(%rbp)
movq $0x0, -0x27c8(%rbp)
movq $0x1, -0x27d0(%rbp)
movq -0x27d0(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x508e
movq -0x27d0(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x9ee0
movq (%rax), %rcx
movq -0x27c0(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x27c0(%rbp)
movaps 0x19008(%rip), %xmm1    # 0x1e040
movq -0x27c0(%rbp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x19004(%rip), %xmm1    # 0x1e050
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
ucomisd -0x27b8(%rbp), %xmm0
jb 0x5075
movq -0x27d0(%rbp), %rax
movq %rax, -0x27c8(%rbp)
jmp 0x508e
jmp 0x5077
movq -0x27d0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x27d0(%rbp)
jmp 0x4ffc
movq -0x27c8(%rbp), %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0x2828(%rbp)
callq 0x9ee0
movq -0x27f0(%rbp), %rdi
movq $0x0, (%rax)
movq -0x27c8(%rbp), %rsi
movq %rsi, -0x2830(%rbp)
callq 0x9ee0
movq -0x2830(%rbp), %rsi
movq -0x2828(%rbp), %rdx
movq -0x27f0(%rbp), %rcx
movq %rsi, (%rax)
movq -0x10(%rbp), %rdi
movq -0x27c8(%rbp), %rsi
callq 0x5170
jmp 0x50f0
jmp 0x50f2
movq -0x27a0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x27a0(%rbp)
jmp 0x4efa
movb $0x1, -0x5d(%rbp)
leaq -0x1400(%rbp), %rdi
callq 0x9900
testb $0x1, -0x5d(%rbp)
jne 0x512b
movq -0x27f0(%rbp), %rdi
callq 0xa130
leaq -0x40(%rbp), %rdi
callq 0xa130
movq -0x27e8(%rbp), %rax
addq $0x2830, %rsp           # imm = 0x2830
popq %rbp
retq
movq -0x27f0(%rbp), %rdi
callq 0xa130
leaq -0x40(%rbp), %rdi
callq 0xa130
movq -0x58(%rbp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)