Qu’est-ce qu’un arbre qui enjambe ?

Étant donné un diagramme non orienté et associé, G=( V,E), un arbre traversant du diagramme est un arbre G qui s’étend sur G (c’est-à-dire qu’il incorpore chaque sommet de ) et est un sous-graphe de (chaque bord de l’arbre a une place avec )

Qu’est-ce qu’un arbre de base ?

La dépense de l’arbre traversant est l’ensemble des charges du nombre considérable d’arêtes de l’arbre. Il peut y en avoir beaucoup qui s’étalent sur les arbres. L’arbre qui traverse le moins est celui dont la dépense est la moins élevée parmi tous les arbres qui se répartissent. De même, il peut y avoir de nombreuses bases réparties sur les arbres.

La moindre propagation sur l’arbre a une application directe dans le plan des systèmes. Il est utilisé dans les calculs approximatifs de l’émission des représentants de commerce itinérants, de l’émission multi-terminaux à moindre coupe et de la coordination impeccable à moindre coût pondéré. D’autres applications fonctionnelles sont :

Enquête de groupe

Reconnaissance de la calligraphie

Division des images

Le calcul de Kruskal

Kruskal’s Calculation fabrique l’étalement sur un arbre en incluant les arêtes individuellement dans un arbre croisé en développement. Le calcul de Kruskal poursuit une méthodologie enthousiaste car, à chaque cycle, il trouve une lisière qui a le moins de poids et l’ajoute à l’étalement en développement sur l’arbre.

Étapes du CaAlgorithme :

Triez les bords du graphique en fonction de leur poids.

Commencez à ajouter des bords au MST, du bord ayant le plus petit poids jusqu’au bord ayant le plus grand poids.

N’ajoutez que des arêtes qui ne forment pas un cycle, des arêtes qui ne relient que des composants déconnectés.

 La question est donc maintenant de savoir comment vérifier si les sommets sont connectés ou non ?

Cela devrait être possible en utilisant la DFS qui part du sommet principal, à ce moment-là il faut vérifier si le sommet suivant est visité ou non. Cependant, la DFS rendra la complexité du temps énorme car elle demande où se trouve la quantité de sommets, le nombre d’arêtes. Le meilleur arrangement est donc celui des “ensembles disjoints” :

Les ensembles disjoints seront des ensembles dont la convergence est l’ensemble non rempli, ce qui implique qu’ils ne partagent pratiquement aucune composante.

Dans le calcul de Kruskal, à chaque cycle, nous choisirons le bord ayant le poids le plus réduit. Dans cette optique, nous commencerons par l’arête pondérée la plus réduite, c’est-à-dire les arêtes ayant un poids de 1. Ensuite, nous choisirons la deuxième arête pondérée la plus minimale, c’est-à-dire l’arête de poids 2. Remarquez que ces deux bords sont absolument disjoints. Actuellement, le bord suivant sera le troisième bord pondéré le plus réduit, c’est-à-dire le bord de poids 3, qui associe les deux bits disjoints du graphique. Actuellement, nous ne sommes pas autorisés à choisir le bord avec le poids 4, qui fera un cycle et nous ne pouvons avoir aucun cycle. Nous allons donc choisir le cinquième bord le moins pondéré, c’est-à-dire le bord de poids 5. Actuellement, les deux autres bords forment des cycles et nous ne les prenons pas en compte. Enfin, nous nous retrouvons avec un arbre de base traversant avec un coût complet de 11 ( = 1 + 2 + 3 + 5).

#inclure <iostream>

#inclure <vecteur>

#inclure <utilité>

#inclure <algorithme>

en utilisant l’espace de noms std ;

const int MAX = 1e4 + 5 ;

int id [MAX], nœuds, bords ;

paire < long long, paire< int, int> > p[MAX] ;

annuler initialiser()

{

    for(int i = 0;i < MAX;++i)

        id[i] = i ;

}

int root(int x)

{

    while(id[x] != x)

    {

        id[x] = id[id[x]] ;

        x = id[x] ;

    }

    retour x ;

}

void union1(int x, int y)

{

    int p = racine(x) ;

    int q = racine(y) ;

    id[p] = id[q] ;

}

long long kruskal(pair< long long, pair< int, int> > p[])

{

    int x, y ;

    long long coût, minimumCost = 0 ;

    for(int i = 0;i < bords;++i)

    {

        // Sélection des bords un par un en ordre croissant depuis le début

        x = p[i]. Deuxièmement. Premièrement ;

        y = p[i]. second. second ;

        coût = p[i]. d’abord ;

        // Vérifier si le bord sélectionné crée un cycle ou non

        if(root(x) != root(y))

        {

            minimumCost += coût ;

            union1(x, y) ;

        }    

    }

    retour minimumCost ;

}

int main()

{

    int x, y ;

    long long poids, coût, minimumCost ;

    initialiser() ;

    cin >> nœuds >> bords ;

    for(int i = 0;i < bords;++i)

    {

        cin >> x >> y >> poids ;

        p[i] = make_pair(poids, make_pair(x, y)) ;

    }

    // Trier les bords dans l’ordre croissant

    tri(p, p + bords) ;

    minimumCost = kruskal(p) ;

    cout << minimumCost << endl ;

    renvoie 0 ;

}

Algorithme de Prim

Prim’s Calculation utilise également la méthode Covetous pour localiser l’arbre qui traverse la base. Dans le Calcul de Demure, nous devenons l’arbre traversant à partir d’une position de départ. Contrairement à une arête dans le cas de Kruskal, nous ajoutons un sommet à l’étalement en développement sur un arbre dans le cas de Prim.

Étapes de calcul :

Maintenir deux arrangements disjoints de sommets. L’un contenant des sommets qui sont en développement et qui s’étendent sur l’arbre et l’autre qui ne sont pas dans l’arbre de croisement en développement.

Choisissez le sommet le moins cher qui est associé à l’arbre traversant en développement et qui n’est pas dans l’arbre traversant en développement et incluez-le dans l’arbre traversant en développement. Cela devrait être possible en utilisant les lignes de besoins. Complétez les sommets associés à l’arbre traversant en développement par la ligne de besoin.

Vérifiez les cycles. Pour ce faire, marquez les centres qui ont été choisis jusqu’à présent et complétez uniquement les centres de la ligne des besoins qui ne sont pas vérifiés.

Dans le calcul de Prim, nous commencerons par un centre discrétionnaire (peu importe lequel) et nous l’imprimerons. Dans chaque cycle, nous vérifierons un autre sommet qui est voisin de celui que nous venons d’estampiller. Le calcul de Demure choisira le bord le moins cher et imprimera le sommet. Dans le cycle suivant, nous avons trois choix, les arêtes de poids 2, 3 et 4. De cette façon, nous choisirons l’arête de poids 2 et imprimerons le sommet. Actuellement, nous avons à nouveau trois possibilités : les arêtes de poids 3, 4 et 5. Cependant, nous ne pouvons pas choisir l’arête avec le poids 3 car elle forme un cycle. Nous choisirons donc l’arête de poids 4 et nous obtiendrons l’arbre de croisement de base de coût absolu 7 ( = 1 + 2 +4).

Mise en œuvre :

#inclure <iostream>

#inclure <vecteur>

#inclure <queue>

#inclure <fonctionnel>

#inclure <utilité>

en utilisant l’espace de noms std ;

const int MAX = 1e4 + 5 ;

typedef pair< long long, int> PII ;

bool marqué [MAX] ;

vecteur < PII> adj[MAX] ;

long long prim(int x)

{

    priority_queue< PII, vector< PII>, greater< PII> > Q ;

    int y ;

    long long minimumCost = 0 ;

    PII p ;

    Q. push(make_pair(0, x)) ;

    while( ! Q. empty())

    {

        // Sélectionner le bord avec un poids minimum

        p = Q. top() ;

        Q. pop() ;

        x = p. seconde ;

        // Vérification du cycle

        if(marked[x] == true)

            continuer ;

        minimumCost += p. d’abord ;

        marqué [x] = vrai ;

        for(int i = 0;i < adj[x]. size();++i)

        {

            y = adj[x][i]. seconde ;

            if(marked[y] == false)

                Q. push(adj[x][i]) ;

        }

    }

    retour minimumCost ;

}

int main()

{

    int nœuds, bords, x, y ;

    long long poids, minimumCost ;

    cin >> nœuds >> bords ;

    for(int i = 0;i < bords;++i)

    {

        cin >> x >> y >> poids ;

        adj[x]. push_back(make_pair(weight, y)) ;

        adj[y]. push_back(make_pair(weight, x)) ;

    }

    // Sélection de 1 comme noeud de départ

    minimumCost = prim(1) ;

    cout << minimumCost << endl ;

    renvoie 0 ;

}