// File: Manca[P]algorithms1/./assignment4.hpp
// Function: assignment4::computeSCC(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void computeSCC(const string& fileName)
    {
        cout << "***** ASSIGNMENT4 MAIN TEST CASE *****" << endl;
        // load from file
        Graph G, Grev;
        ifstream file(fileName, ios::in);
        for (int i = 1; i < NUM_NODES; i++)
        {
            G[i] = std::vector<int>();
            Grev[i] = std::vector<int>();
        }
        
        cout << "Reading file..." << endl;
        std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
        if (file.is_open())
        {
            std::string rawInput;
            int tail, head;
            while (getline(file, rawInput))
            {
                std::istringstream is(rawInput);

                is >> tail;
                is >> head;
                
                G[tail].push_back(head);
                Grev[head].push_back(tail);
            }
            file.close();
        }
        std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
        std::cout << "Done. Time took to read the whole file and construct two graphs: "
        << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
        << "ms.\n";
        
        // initialize global vars
        _seen       = seenList(G.size() + 1, 0);
        _times      = timesList(G.size() + 1, 0);
        _leaders    = leadersList(G.size() + 1, 0);
 
        DFSLoop(Grev);
        
        Graph newGraph = constructNewGraph(G, _times);
        DFSLoop(newGraph);
        
        sort(_leaders.begin(), _leaders.end());
        std::vector<SCC> SCCs;
        int el = _leaders[1];
        int elCnt = 1;
        for (size_t i = 2; i < _leaders.size(); i++)
        {
            if (_leaders[i] == el)
                elCnt++;
            else
            {
                SCC scc;
                scc.leader = el;
                scc.numNodes = elCnt;
                SCCs.push_back(scc);
                
                el = _leaders[i];
                elCnt = 1;
            }
        }
        // last SCC
        SCC scc;
        scc.leader = el;
        scc.numNodes = elCnt;
        SCCs.push_back(scc);
        
        cout << " Total number of SCCs is: " << SCCs.size() << endl << "Top 5 are: " << endl;
        
        // Let's just sort them in descending order by number of components
        sort(SCCs.begin(), SCCs.end(), compareByNumSCCs);
        
        for (int i = 0; i < 5; i++)
        {
            cout << "SCC with leader " << SCCs[i].leader << " has " << SCCs[i].numNodes << " nodes." << endl;
        }
        
        // Correct result is: 434821,968,459,313,211
        assert(SCCs[0].numNodes == 434821);
        assert(SCCs[1].numNodes == 968);
        assert(SCCs[2].numNodes == 459);
        assert(SCCs[3].numNodes == 313);
        assert(SCCs[4].numNodes == 211);
    }

// Assembly:
subq $0x688, %rsp            # imm = 0x688
movq %rdi, 0x680(%rsp)
movq 0x1ee52(%rip), %rdi     # 0x23fd8
leaq 0x14fbb(%rip), %rsi     # 0x1a148
callq 0x21a0
movq %rax, %rdi
movq 0x1ee2c(%rip), %rsi     # 0x23fc8
callq 0x21d0
leaq 0x650(%rsp), %rdi
callq 0x8760
leaq 0x620(%rsp), %rdi
callq 0x8760
movq 0x680(%rsp), %rsi
leaq 0x418(%rsp), %rdi
movl $0x8, %edx
callq 0x22c0
jmp 0x51d7
movl $0x1, 0x408(%rsp)
cmpl $0xd5cc3, 0x408(%rsp) # imm = 0xD5CC3
jge 0x5340
xorps %xmm0, %xmm0
movaps %xmm0, 0x3f0(%rsp)
movq $0x0, 0x400(%rsp)
leaq 0x3f0(%rsp), %rdi
callq 0x7f80
leaq 0x650(%rsp), %rdi
leaq 0x408(%rsp), %rsi
callq 0x8530
movq %rax, 0x110(%rsp)
jmp 0x5236
movq 0x110(%rsp), %rdi
leaq 0x3f0(%rsp), %rsi
movq %rsi, 0x100(%rsp)
callq 0x8720
movq 0x100(%rsp), %rdi
callq 0x8300
xorps %xmm0, %xmm0
movaps %xmm0, 0x3d0(%rsp)
movq $0x0, 0x3e0(%rsp)
leaq 0x3d0(%rsp), %rdi
callq 0x7f80
leaq 0x620(%rsp), %rdi
leaq 0x408(%rsp), %rsi
callq 0x8530
movq %rax, 0x108(%rsp)
jmp 0x52a3
movq 0x108(%rsp), %rdi
leaq 0x3d0(%rsp), %rsi
callq 0x8720
leaq 0x3d0(%rsp), %rdi
callq 0x8300
movl 0x408(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x408(%rsp)
jmp 0x51e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
jmp 0x5d6d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x3f0(%rsp), %rdi
callq 0x8300
jmp 0x5d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x3d0(%rsp), %rdi
callq 0x8300
jmp 0x5d60
movq 0x1ec91(%rip), %rdi     # 0x23fd8
leaq 0x14e21(%rip), %rsi     # 0x1a16f
callq 0x21a0
movq %rax, 0xf8(%rsp)
jmp 0x535d
movq 0xf8(%rsp), %rdi
movq 0x1ec5c(%rip), %rsi     # 0x23fc8
callq 0x21d0
jmp 0x5373
callq 0x2240
movq %rax, 0x3c8(%rsp)
leaq 0x418(%rsp), %rdi
callq 0x22b0
movb %al, 0xf7(%rsp)
jmp 0x5396
movb 0xf7(%rsp), %al
testb $0x1, %al
jne 0x53a6
jmp 0x554c
leaq 0x3a8(%rsp), %rdi
callq 0x2260
leaq 0x418(%rsp), %rdi
leaq 0x3a8(%rsp), %rsi
callq 0x2050
movq %rax, 0xe8(%rsp)
jmp 0x53d2
movq 0xe8(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x2210
movb %al, 0xe7(%rsp)
jmp 0x53f2
movb 0xe7(%rsp), %al
testb $0x1, %al
jne 0x5402
jmp 0x551c
leaq 0x220(%rsp), %rdi
leaq 0x3a8(%rsp), %rsi
movl $0x8, %edx
callq 0x22f0
jmp 0x541e
leaq 0x220(%rsp), %rdi
leaq 0x3a4(%rsp), %rsi
callq 0x2120
jmp 0x5435
leaq 0x220(%rsp), %rdi
leaq 0x3a0(%rsp), %rsi
callq 0x2120
jmp 0x544c
leaq 0x650(%rsp), %rdi
leaq 0x3a4(%rsp), %rsi
callq 0x8530
movq %rax, 0xd8(%rsp)
jmp 0x546b
movq 0xd8(%rsp), %rdi
leaq 0x3a0(%rsp), %rsi
callq 0x7fd0
jmp 0x5482
leaq 0x620(%rsp), %rdi
leaq 0x3a0(%rsp), %rsi
callq 0x8530
movq %rax, 0xd0(%rsp)
jmp 0x54a1
movq 0xd0(%rsp), %rdi
leaq 0x3a4(%rsp), %rsi
callq 0x7fd0
jmp 0x54b8
leaq 0x220(%rsp), %rdi
callq 0x20d0
jmp 0x53b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
jmp 0x5d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
jmp 0x553a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x220(%rsp), %rdi
callq 0x20d0
jmp 0x553a
leaq 0x418(%rsp), %rdi
callq 0x2060
jmp 0x552b
leaq 0x3a8(%rsp), %rdi
callq 0x2130
jmp 0x554c
leaq 0x3a8(%rsp), %rdi
callq 0x2130
jmp 0x5d60
callq 0x2240
movq %rax, 0x218(%rsp)
movq 0x1ea78(%rip), %rdi     # 0x23fd8
leaq 0x14c18(%rip), %rsi     # 0x1a17f
callq 0x21a0
movq %rax, 0xc8(%rsp)
jmp 0x5576
leaq 0x218(%rsp), %rdi
leaq 0x3c8(%rsp), %rsi
callq 0x8b70
movq %rax, 0xc0(%rsp)
jmp 0x5595
movq 0xc0(%rsp), %rax
movq %rax, 0x208(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x8b40
movq %rax, 0xb8(%rsp)
jmp 0x55bc
movq 0xb8(%rsp), %rax
movq %rax, 0x210(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x8bc0
movq %rax, 0xb0(%rsp)
jmp 0x55e3
movq 0xb0(%rsp), %rsi
movq 0xc8(%rsp), %rdi
callq 0x2350
movq %rax, 0xa8(%rsp)
jmp 0x5602
movq 0xa8(%rsp), %rdi
leaq 0x14bb0(%rip), %rsi     # 0x1a1c1
callq 0x21a0
jmp 0x5618
leaq 0x650(%rsp), %rdi
callq 0x8690
incq %rax
movq %rax, 0x98(%rsp)
movl $0x0, 0x1ec(%rsp)
leaq 0x1eb(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x83d0
movq 0x98(%rsp), %rsi
movq 0xa0(%rsp), %rcx
leaq 0x1f0(%rsp), %rdi
leaq 0x1ec(%rsp), %rdx
callq 0x86a0
jmp 0x5677
leaq 0x1eb8a(%rip), %rdi     # 0x24208
leaq 0x1f0(%rsp), %rsi
movq %rsi, 0x80(%rsp)
callq 0x8720
movq 0x80(%rsp), %rdi
callq 0x8300
leaq 0x1eb(%rsp), %rdi
callq 0x8470
leaq 0x650(%rsp), %rdi
callq 0x8690
incq %rax
movq %rax, 0x88(%rsp)
movl $0x0, 0x1cc(%rsp)
leaq 0x1cb(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x83d0
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rcx
leaq 0x1d0(%rsp), %rdi
leaq 0x1cc(%rsp), %rdx
callq 0x86a0
jmp 0x570c
leaq 0x1eadd(%rip), %rdi     # 0x241f0
leaq 0x1d0(%rsp), %rsi
movq %rsi, 0x68(%rsp)
callq 0x8720
movq 0x68(%rsp), %rdi
callq 0x8300
leaq 0x1cb(%rsp), %rdi
callq 0x8470
leaq 0x650(%rsp), %rdi
callq 0x8690
incq %rax
movq %rax, 0x70(%rsp)
movl $0x0, 0x1ac(%rsp)
leaq 0x1ab(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x83d0
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rcx
leaq 0x1b0(%rsp), %rdi
leaq 0x1ac(%rsp), %rdx
callq 0x86a0
jmp 0x578f
leaq 0x1ea8a(%rip), %rdi     # 0x24220
leaq 0x1b0(%rsp), %rsi
movq %rsi, 0x60(%rsp)
callq 0x8720
movq 0x60(%rsp), %rdi
callq 0x8300
leaq 0x1ab(%rsp), %rdi
callq 0x8470
leaq 0x620(%rsp), %rdi
callq 0x3160
jmp 0x57ce
leaq 0x1ea1b(%rip), %rdx     # 0x241f0
leaq 0x178(%rsp), %rdi
leaq 0x650(%rsp), %rsi
callq 0x3270
jmp 0x57ec
leaq 0x178(%rsp), %rdi
callq 0x3160
jmp 0x57fb
leaq 0x1ea1e(%rip), %rdi     # 0x24220
movq %rdi, 0x58(%rsp)
callq 0x8360
movq 0x58(%rsp), %rdi
movq %rax, 0x170(%rsp)
callq 0x8480
movq %rax, 0x168(%rsp)
movq 0x170(%rsp), %rdi
movq 0x168(%rsp), %rsi
callq 0x88d0
jmp 0x583d
leaq 0x150(%rsp), %rdi
callq 0x8970
leaq 0x1e9cf(%rip), %rdi     # 0x24220
movl $0x1, %esi
callq 0x84b0
movl (%rax), %eax
movl %eax, 0x14c(%rsp)
movl $0x1, 0x148(%rsp)
movq $0x2, 0x140(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0x1e991(%rip), %rdi     # 0x24220
callq 0x7f90
movq %rax, %rcx
movq 0x50(%rsp), %rax
cmpq %rcx, %rax
jae 0x5a07
movq 0x140(%rsp), %rsi
leaq 0x1e96c(%rip), %rdi     # 0x24220
callq 0x84b0
movl (%rax), %eax
cmpl 0x14c(%rsp), %eax
jne 0x5969
movl 0x148(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x148(%rsp)
jmp 0x59ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x1eb(%rsp), %rdi
callq 0x8470
jmp 0x5d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x1cb(%rsp), %rdi
callq 0x8470
jmp 0x5d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x1ab(%rsp), %rdi
callq 0x8470
jmp 0x5d60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
jmp 0x5d53
movl 0x14c(%rsp), %eax
movl %eax, 0x138(%rsp)
movl 0x148(%rsp), %eax
movl %eax, 0x13c(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x8980
jmp 0x599c
movq 0x140(%rsp), %rsi
leaq 0x1e875(%rip), %rdi     # 0x24220
callq 0x84b0
movl (%rax), %eax
movl %eax, 0x14c(%rsp)
movl $0x1, 0x148(%rsp)
jmp 0x59ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x410(%rsp)
movl %eax, 0x40c(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x8ae0
jmp 0x5d53
jmp 0x59ee
movq 0x140(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x140(%rsp)
jmp 0x587b
movl 0x14c(%rsp), %eax
movl %eax, 0x130(%rsp)
movl 0x148(%rsp), %eax
movl %eax, 0x134(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x8980
jmp 0x5a3a
movq 0x1e597(%rip), %rdi     # 0x23fd8
leaq 0x1477e(%rip), %rsi     # 0x1a1c6
callq 0x21a0
movq %rax, 0x48(%rsp)
jmp 0x5a54
leaq 0x150(%rsp), %rdi
callq 0x89f0
movq 0x48(%rsp), %rdi
movq %rax, %rsi
callq 0x2070
movq %rax, 0x40(%rsp)
jmp 0x5a75
movq 0x40(%rsp), %rdi
movq 0x1e547(%rip), %rsi     # 0x23fc8
callq 0x21d0
movq %rax, 0x38(%rsp)
jmp 0x5a8d
movq 0x38(%rsp), %rdi
leaq 0x14748(%rip), %rsi     # 0x1a1e1
callq 0x21a0
movq %rax, 0x30(%rsp)
jmp 0x5aa5
movq 0x30(%rsp), %rdi
movq 0x1e517(%rip), %rsi     # 0x23fc8
callq 0x21d0
jmp 0x5ab8
leaq 0x150(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x8a10
movq 0x28(%rsp), %rdi
movq %rax, 0x128(%rsp)
callq 0x8a40
movq %rax, 0x120(%rsp)
movq 0x128(%rsp), %rdi
movq 0x120(%rsp), %rsi
leaq -0x25bb(%rip), %rdx     # 0x3540
callq 0x8bd0
jmp 0x5b02
movl $0x0, 0x11c(%rsp)
cmpl $0x5, 0x11c(%rsp)
jge 0x5bdf
movq 0x1e4b6(%rip), %rdi     # 0x23fd8
leaq 0x145d1(%rip), %rsi     # 0x1a0fa
callq 0x21a0
movq %rax, 0x20(%rsp)
jmp 0x5b35
movslq 0x11c(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0x8c20
movq 0x20(%rsp), %rdi
movl (%rax), %esi
callq 0x2320
movq %rax, 0x18(%rsp)
jmp 0x5b5d
movq 0x18(%rsp), %rdi
leaq 0x145a2(%rip), %rsi     # 0x1a10b
callq 0x21a0
movq %rax, 0x10(%rsp)
jmp 0x5b75
movslq 0x11c(%rsp), %rsi
leaq 0x150(%rsp), %rdi
callq 0x8c20
movq 0x10(%rsp), %rdi
movl 0x4(%rax), %esi
callq 0x2320
movq %rax, 0x8(%rsp)
jmp 0x5b9e
movq 0x8(%rsp), %rdi
leaq 0x14567(%rip), %rsi     # 0x1a111
callq 0x21a0
movq %rax, (%rsp)
jmp 0x5bb5
movq (%rsp), %rdi
movq 0x1e408(%rip), %rsi     # 0x23fc8
callq 0x21d0
jmp 0x5bc7
jmp 0x5bc9
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x5b0d
leaq 0x150(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8c20
cmpl $0x6a285, 0x4(%rax)     # imm = 0x6A285
jne 0x5bfb
jmp 0x5c1a
leaq 0x145eb(%rip), %rdi     # 0x1a1ed
leaq 0x1441e(%rip), %rsi     # 0x1a027
movl $0x16c, %edx            # imm = 0x16C
leaq 0x145f3(%rip), %rcx     # 0x1a208
callq 0x2140
leaq 0x150(%rsp), %rdi
movl $0x1, %esi
callq 0x8c20
cmpl $0x3c8, 0x4(%rax)       # imm = 0x3C8
jne 0x5c37
jmp 0x5c56
leaq 0x145f7(%rip), %rdi     # 0x1a235
leaq 0x143e2(%rip), %rsi     # 0x1a027
movl $0x16d, %edx            # imm = 0x16D
leaq 0x145b7(%rip), %rcx     # 0x1a208
callq 0x2140
leaq 0x150(%rsp), %rdi
movl $0x2, %esi
callq 0x8c20
cmpl $0x1cb, 0x4(%rax)       # imm = 0x1CB
jne 0x5c73
jmp 0x5c92
leaq 0x145d3(%rip), %rdi     # 0x1a24d
leaq 0x143a6(%rip), %rsi     # 0x1a027
movl $0x16e, %edx            # imm = 0x16E
leaq 0x1457b(%rip), %rcx     # 0x1a208
callq 0x2140
leaq 0x150(%rsp), %rdi
movl $0x3, %esi
callq 0x8c20
cmpl $0x139, 0x4(%rax)       # imm = 0x139
jne 0x5caf
jmp 0x5cce
leaq 0x145af(%rip), %rdi     # 0x1a265
leaq 0x1436a(%rip), %rsi     # 0x1a027
movl $0x16f, %edx            # imm = 0x16F
leaq 0x1453f(%rip), %rcx     # 0x1a208
callq 0x2140
leaq 0x150(%rsp), %rdi
movl $0x4, %esi
callq 0x8c20
cmpl $0xd3, 0x4(%rax)
jne 0x5ceb
jmp 0x5d0a
leaq 0x1458b(%rip), %rdi     # 0x1a27d
leaq 0x1432e(%rip), %rsi     # 0x1a027
movl $0x170, %edx            # imm = 0x170
leaq 0x14503(%rip), %rcx     # 0x1a208
callq 0x2140
leaq 0x150(%rsp), %rdi
callq 0x8ae0
leaq 0x178(%rsp), %rdi
callq 0x8860
leaq 0x418(%rsp), %rdi
callq 0x2080
leaq 0x620(%rsp), %rdi
callq 0x8860
leaq 0x650(%rsp), %rdi
callq 0x8860
addq $0x688, %rsp            # imm = 0x688
retq
leaq 0x178(%rsp), %rdi
callq 0x8860
leaq 0x418(%rsp), %rdi
callq 0x2080
leaq 0x620(%rsp), %rdi
callq 0x8860
leaq 0x650(%rsp), %rdi
callq 0x8860
movq 0x410(%rsp), %rdi
callq 0x2330
nopw %cs:(%rax,%rax)