// File: /workspace/github_c_makefile_star2_O3/trumabrat[P]GrandProjet/Graphe.c
// Function: chaine_arborescence
ListeEntier chaine_arborescence(Graphe* g, int u, int v){
    // Dans chaque iteration, on prend le sommet a la tete de la file
    // et enfile les sommets adjacent mais non visite
    // on continue cette boucle jusqu'a ce qu'on touche le sommet v

    // securisation
    assert(g);
    assert(u-1 < g->nbsom && v-1 < g->nbsom);
    if(u == v) return 0;

    int sommet_en_cours, a_enfiler;
    Cellule_arete* cell_arete;

    // on cree une table pour l'arborescence
    // qui stocke le sommet pere de chaque sommet
    int pere[g->nbsom];
    for (int i = 0; i < g->nbsom; i++)
    {
        pere[i] = -1;
    }

    // on cree une autre table pour stocker les distances entre u et les sommets
    int distance[g->nbsom];
    for (int i = 0; i < g->nbsom; i++)
    {
        distance[i] = g->nbsom + 1;
    }
    distance[u-1] = 0;

    // on cree une autre table pour stocker l'etat de visite
    // un sommet peut etre 
    //  non visite
    //  ouvert (certains de ses descendant ne sont pas encore visites) 
    //  ferme (tous ses descendant sont visites)
    etat_visite visite[g->nbsom];
    for (int i = 0; i < g->nbsom; i++)
    {
        visite[i] = non_visite;
    }
    visite[u-1] = ouvert;
    
    // on cree un file pour les sommets a visiter
    S_file* file = calloc(1, sizeof(S_file));
    Init_file(file);
    enfile(file, u);

    // on fait un parcourt en largeur jusqu'a ce que la file est vide
    while(!estFileVide(file)){

        // on prend la tete de la file et parcourt sa liste de voisins
        // et enfile les sommets prochains
        sommet_en_cours = defile(file);
        cell_arete = g->T_som[sommet_en_cours-1]->L_voisin;
        while(cell_arete){
            // on teste le numero de sommet a enfiler
            // a_enfiler = cell_arete->a->u == sommet_en_cours ? v : u;
            if(cell_arete->a->u == sommet_en_cours) 
                 a_enfiler = cell_arete->a->v;
            else a_enfiler = cell_arete->a->u;
            
            // si deja visite, on ne prend pas, sinon on le prend et calcule sa distance
            //  et marque son status comme ouvert(en train de visiter)
            //  et memorise son ancetre
            if(visite[a_enfiler-1] == non_visite){
                visite[a_enfiler-1] = ouvert;
                distance[a_enfiler-1] = distance[sommet_en_cours-1]+1;
                pere[a_enfiler-1] = sommet_en_cours;
                enfile(file, a_enfiler);
            }
            cell_arete = cell_arete->suiv;
        }
        visite[sommet_en_cours-1] = ferme;
    }

    // creation et initialisation d'une liste a renvoyer
    ListeEntier chaine_parcourt;
    Init_Liste(&chaine_parcourt);
    
    // le cas ou sommets u et v ne sont pas connexe
    if(pere[v-1] == -1){
        liberer_file(file);
        return chaine_parcourt;
    }

    // traitement pour la liste de parcourt
    // on trouve le pere successivement a partir de v, jusqu'a u
    // ensuite on le stoke dans la liste (il y a une renversement)
    
    sommet_en_cours = v;
    while(sommet_en_cours != u){
        ajoute_en_tete(&chaine_parcourt, sommet_en_cours);
        sommet_en_cours = pere[sommet_en_cours-1];
    }
    ajoute_en_tete(&chaine_parcourt, sommet_en_cours); // on ajoute u

    // liberer memoire
    liberer_file(file);

    return chaine_parcourt;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
testq %rdi, %rdi
je 0x1a1b
movl %esi, %r14d
movq %rdi, %rcx
movl (%rdi), %eax
cmpl %esi, %eax
jl 0x1a3a
movl %edx, %r13d
cmpl %edx, %eax
jl 0x1a3a
cmpl %r13d, %r14d
jne 0x1726
xorl %eax, %eax
jmp 0x1a0c
movq %rsp, -0x58(%rbp)
leal -0x1(%r14), %ebx
movq %rsp, %rdi
leaq 0xf(,%rax,4), %rax
andq $-0x10, %rax
subq %rax, %rdi
movq %rdi, %rsp
movq %rcx, -0x60(%rbp)
movl (%rcx), %r12d
testl %r12d, %r12d
movl %r13d, -0x44(%rbp)
movq %rdi, -0x50(%rbp)
jle 0x18bb
leaq (,%r12,4), %rdx
movl $0xff, %esi
movq %rdx, -0x38(%rbp)
callq 0x10c0
movq %rsp, %rcx
leaq 0xf(,%r12,4), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x30(%rbp)
movq %rcx, %rsp
leal 0x1(%r12), %ecx
leal 0x3(%r12), %edx
leaq -0x1(%r12), %rsi
movq %rsi, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shrl $0x2, %edx
shlq $0x4, %rdx
movdqa 0x286e(%rip), %xmm1     # 0x4020
movdqa 0x2876(%rip), %xmm2     # 0x4030
xorl %esi, %esi
movdqa 0x287c(%rip), %xmm3     # 0x4040
pxor %xmm3, %xmm0
pcmpeqd %xmm4, %xmm4
movdqa 0x287c(%rip), %xmm5     # 0x4050
movdqa %xmm2, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
movd %xmm6, %edi
notl %edi
testb $0x1, %dil
je 0x1810
movq -0x30(%rbp), %rdi
movl %ecx, (%rdi,%rsi)
pxor %xmm4, %xmm6
pextrw $0x4, %xmm6, %edi
testb $0x1, %dil
je 0x1827
movq -0x30(%rbp), %rdi
movl %ecx, 0x4(%rdi,%rsi)
movdqa %xmm1, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
pxor %xmm4, %xmm6
pextrw $0x0, %xmm6, %edi
testb $0x1, %dil
je 0x1867
movq -0x30(%rbp), %rdi
movl %ecx, 0x8(%rdi,%rsi)
pextrw $0x4, %xmm6, %edi
testb $0x1, %dil
je 0x187a
movq -0x30(%rbp), %rdi
movl %ecx, 0xc(%rdi,%rsi)
paddq %xmm5, %xmm2
paddq %xmm5, %xmm1
addq $0x10, %rsi
cmpq %rsi, %rdx
jne 0x17d4
movslq %ebx, %rbx
movq -0x30(%rbp), %rcx
movl $0x0, (%rcx,%rbx,4)
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
testl %r12d, %r12d
jle 0x18e7
movq %r13, %rdi
xorl %esi, %esi
movq -0x38(%rbp), %rdx
callq 0x10c0
jmp 0x18e7
movq %rsp, %rcx
leaq 0xf(,%r12,4), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, %rsp
movslq %ebx, %rbx
movq %rcx, -0x30(%rbp)
movl $0x0, (%rcx,%rbx,4)
movq %rsp, %r13
subq %rax, %r13
movq %r13, %rsp
movl $0x1, (%r13,%rbx,4)
movl $0x1, %edi
movl $0x10, %esi
callq 0x10e0
movq %rax, %rbx
movq %rax, %rdi
callq 0x3350
movq %rbx, %rdi
movq %r14, -0x38(%rbp)
movl %r14d, %esi
callq 0x3361
movq %rbx, %rdi
callq 0x3357
testl %eax, %eax
jne 0x19ae
movq %rbx, %r15
movq %rbx, %rdi
callq 0x339c
movl %eax, %ebx
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movslq %ebx, %r14
movq -0x8(%rax,%r14,8), %rax
decq %r14
movq 0x18(%rax), %r12
testq %r12, %r12
je 0x199a
movq (%r12), %rcx
movl (%rcx), %eax
cmpl %ebx, %eax
jne 0x195f
movl 0x4(%rcx), %eax
movslq %eax, %rsi
cmpl $0x0, -0x4(%r13,%rsi,4)
jne 0x1993
leaq -0x1(%rsi), %rax
movl $0x1, (%r13,%rax,4)
movq -0x30(%rbp), %rdx
movl (%rdx,%r14,4), %ecx
incl %ecx
movl %ecx, (%rdx,%rax,4)
movq -0x50(%rbp), %rcx
movl %ebx, (%rcx,%rax,4)
movq %r15, %rdi
callq 0x3361
movq 0x8(%r12), %r12
jmp 0x194d
movl $0x2, (%r13,%r14,4)
movq %r15, %rbx
movq %r15, %rdi
jmp 0x191c
leaq -0x40(%rbp), %rdi
callq 0x33f8
movl -0x44(%rbp), %r15d
movslq %r15d, %rax
movq -0x50(%rbp), %r12
cmpl $-0x1, -0x4(%r12,%rax,4)
je 0x19fc
movq %rbx, %r13
leaq -0x40(%rbp), %rbx
movq -0x38(%rbp), %r14
movq %rbx, %rdi
movl %r15d, %esi
callq 0x340a
movslq %r15d, %rax
movl -0x4(%r12,%rax,4), %r15d
cmpl %r14d, %r15d
jne 0x19d5
leaq -0x40(%rbp), %rdi
movl %r14d, %esi
callq 0x340a
movq %r13, %rbx
movq %rbx, %rdi
callq 0x33c3
movq -0x40(%rbp), %rax
movq -0x58(%rbp), %rsp
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x267f(%rip), %rdi      # 0x40a1
leaq 0x2651(%rip), %rsi      # 0x407a
leaq 0x26bc(%rip), %rcx      # 0x40ec
movl $0xbe, %edx
callq 0x10b0
leaq 0x26df(%rip), %rdi      # 0x4120
leaq 0x2632(%rip), %rsi      # 0x407a
leaq 0x269d(%rip), %rcx      # 0x40ec
movl $0xbf, %edx
callq 0x10b0