Was ist ein Spanning Tree?

Bei einem ungerichteten und verknüpften Diagramm ist G=( V,E) ein durchlaufender Baum des Diagramms ein Baum G, der G umfasst (d.h. er umfasst jeden Scheitelpunkt von ) und ein Unterdiagramm von ist (jede Kante im Baum hat einen Platz mit )

Was ist ein Basisspannender Baum?

Die Kosten des Traversenbaums sind die Summe der Lasten der beträchtlichen Anzahl von Kanten im Baum. Es können viele über Bäume verteilt sein. Der am wenigsten überfahrende Baum ist der überfahrende Baum, bei dem die Kosten von allen überfahrenden Bäumen am geringsten sind. Ebenso kann es zahlreiche über Bäume verteilte Stützpunkte geben.

Die geringste Ausbreitung über den Baum hat direkte Anwendung im Plan der Systeme. Sie wird in Berechnungen zur Annäherung an das Problem des reisenden Handelsvertreters, des Multi-Terminal Least Cut Issue und der am wenigsten kostengewichteten tadellosen Koordination verwendet. Andere funktionelle Anwendungen sind:

Untersuchung der Gruppe

Danksagung der Schreibkunst

Bildteilung

Kruskals Berechnung

Kruskals Berechnung stellt die Ausbreitung über einen Baum her, indem Kanten einzeln in einen sich entwickelnden Kreuzungsbaum einbezogen werden. Kruskals Berechnung verfolgt eine eifrige Methodik, da sie in jedem Zyklus eine Kante mit dem geringsten Gewicht findet und diese zur sich entwickelnden Ausbreitung über den Baum hinzufügt.

CaAlgorithmus-Schritte:

Sortieren Sie die Diagrammkanten in Bezug auf ihre Gewichte.

Beginnen Sie mit dem Hinzufügen von Kanten zur MST von der Kante mit dem kleinsten Gewicht bis zur Kante mit dem größten Gewicht.

Fügen Sie nur Kanten hinzu, die keinen Zyklus bilden, Kanten, die nur unverbundene Komponenten verbinden.

 Nun stellt sich also die Frage, wie überprüft werden kann, ob Scheitelpunkte miteinander verbunden sind oder nicht ?

Dies sollte unter Verwendung der DFS möglich sein, die vom Hauptverkehrspunkt ausgeht und an diesem Punkt prüft, ob der nachfolgende Verkehrspunkt besucht wird oder nicht. Dennoch wird die DFS die Zeitkompliziertheit enorm erhöhen, da sie eine Anfrage nach der Anzahl der Vertices und der Anzahl der Kanten hat. Die beste Anordnung ist also “Disjunkte Mengen”:

Disjunkte Mengen werden Mengen sein, deren Konvergenz die ungefüllte Menge ist, so dass dies impliziert, dass sie im Grunde genommen keine gemeinsame Komponente haben.

In Kruskals Berechnung wählen wir bei jedem Zyklus die Kante mit dem am meisten reduzierten Gewicht. In diesem Sinne beginnen wir zuerst mit der am stärksten gewichteten Kante, d.h. mit den Kanten mit dem Gewicht 1. Danach wählen wir die am zweitwenigsten gewichtete Kante, d.h. die Kante mit dem Gewicht 2. Beachten Sie, dass diese beiden Kanten absolut unzusammenhängend sind. Gegenwärtig ist die folgende Kante die drittreduzierteste gewichtete Kante, d.h. die Kante mit der Gewichtung 3, die die beiden disjunkten Bits des Diagramms miteinander verbindet. Gegenwärtig ist es uns nicht erlaubt, die Kante mit der Gewichtung 4 zu wählen, das ergibt einen Zyklus, und wir können keine Zyklen haben. Wir werden also die am wenigsten gewichtete Kante wählen, d.h. die Kante mit der Gewichtung 5. Gegenwärtig werden die beiden anderen Kanten Zyklen bilden, so dass wir sie außer Acht lassen werden. Am Ende erhalten wir einen Basis-Traversenbaum mit vollständigen Kosten 11 ( = 1 + 2 + 3 + 5).

#einschließen < iostream>

#einschließen <Vektor>

#einschließen <Dienstprogramm>

#einschließen <Algorithmus>

unter Verwendung des Namensraums std;

const int MAX = 1e4 + 5;

int id[MAX], Knoten, Kanten;

Paar < lang lang, Paar< int, int> > p[MAX];

void initialize()

{

    für(int i = 0;i < MAX;++i)

        id[i] = i;

}

int root(int x)

{

    während(id[x] != x)

    {

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

        x = Id[x];

    }

    Rückgabe x;

}

ungültige Vereinigung1(int x, int y)

{

    int p = Wurzel(x);

    int q = Wurzel(y);

    id[p] = id[q];

}

lang lang kruskal(Paar< lang lang, Paar< int, int> > p[])

{

    int x, y;

    lange lange Kosten, MinimumKosten = 0;

    für(int i = 0;i < Kanten;++i)

    {

        // Auswahl der Kanten nacheinander in aufsteigender Reihenfolge von Anfang an

        x = p[i]. zweite. erste;

        y = p[i]. Sekunde;

        Kosten = p[i]. zuerst;

        // Prüfen Sie, ob die ausgewählte Kante einen Zyklus erzeugt oder nicht

        if(Wurzel(x) != Wurzel(y))

        {

            minimumKosten += Kosten;

            Gewerkschaft1(x, y);

        }    

    }

    Rückgabe MinimumKosten;

}

int main()

{

    int x, y;

    lang lang Gewicht, Kosten, MinimumKosten;

    initialize();

    cin >> Knoten >> Kanten;

    für(int i = 0;i < Kanten;++i)

    {

        cin >> x >> y >> Gewicht;

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

    }

    // Sortieren Sie die Kanten in aufsteigender Reihenfolge

    sortieren(p, p + Kanten);

    minimumKosten = kruskal(p);

    cout << minimale Kosten <<< endl;

    0 zurückgeben;

}

Prim’scher Algorithmus

Prims Berechnung verwendet ebenfalls die Covetous-Methode zur Lokalisierung des Basistraversenbaums. In der Berechnung von Demure werden wir von einer Anfangsposition aus zum Traversierbaum. Im Gegensatz zu einer Kante in Kruskal’s fügen wir in Prim’s der sich entwickelnden Ausbreitung über einen Baum einen Scheitelpunkt hinzu.

Berechnungsschritte:

Halten Sie zwei unzusammenhängende Anordnungen von Scheitelpunkten aufrecht. Eine enthält Knoten, die sich in der Entwicklung befinden und sich über den Baum ausbreiten, und eine andere, die sich nicht im sich entwickelnden Kreuzungsbaum befindet.

Wählen Sie den günstigsten Knoten, der mit dem sich entwickelnden Kreuzungsbaum verbunden ist und nicht im sich entwickelnden Kreuzungsbaum enthalten ist, und schließen Sie ihn in die sich entwickelnde Ausbreitung über einen Baum ein. Dies sollte unter Verwendung von Need Lines möglich sein. Ergänzen Sie die Eckpunkte, die mit dem sich entwickelnden Kreuzungsbaum verbunden sind, in der Bedarfslinie.

Prüfen Sie auf Zyklen. Markieren Sie dazu die Knotenpunkte, die ab jetzt ausgewählt wurden, und ergänzen Sie nur die Knotenpunkte in der Need Line, die nicht angekreuzt sind.

In Prim’s Calculation beginnen wir mit einem diskretionären Hub (es spielt keine Rolle, welcher) und prägen ihn ein. In jedem Zyklus werden wir einen anderen Knotenpunkt überprüfen, der dem soeben eingeprägten benachbart ist. Als Begehrlichkeitsberechnung wird die Berechnung von Demure die kostengünstigste Kante wählen und den Scheitelpunkt einprägen. Wir wählen also grundsätzlich die Kante mit dem Gewicht 1. Im folgenden Zyklus haben wir drei Auswahlmöglichkeiten, Kanten mit dem Gewicht 2, 3 und 4. Auf diese Weise werden wir die Kante mit dem Gewicht 2 wählen und den Scheitelpunkt einprägen. Gegenwärtig haben wir wieder drei Alternativen, Kanten mit den Gewichten 3, 4 und 5. Wir können jedoch nicht die Kante mit der Gewichtung 3 wählen, da sie einen Zyklus bildet. Also wählen wir die Kante mit der Gewichtung 4 und erhalten den Basiskreuzungsbaum mit den absoluten Kosten 7 ( = 1 + 2 +4).

Durchführung:

#einschließen < iostream>

#einschließen <Vektor>

#einschließen <Warteschlange>

#einschließen <funktional>

#einschließen <Dienstprogramm>

unter Verwendung des Namensraums std;

const int MAX = 1e4 + 5;

typedef-Paar< lang lang, int> PII;

bool markiert[MAX];

Vektor < PII> adj[MAX];

lang lang prim(int x)

{

    Priorität_Warteschlange< PII, Vektor< PII>, größer< PII> > Q;

    int y;

    lang lang minimalKosten = 0;

    PII p;

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

    while(! Q. leer())

    {

        // Wählen Sie die Kante mit dem Mindestgewicht

        p = Q. oben();

        F. pop();

        x = p. Sekunde;

        // Prüfung auf Zyklus

        if(markiert[x] == wahr)

            weiter;

        MinimumKosten += p. zuerst;

        markiert[x] = wahr;

        for(int i = 0;i < adj[x]. Größe();++i)

        {

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

            if(markiert[y] == falsch)

                Q. Drücken Sie (adj[x][i]);

        }

    }

    Rückgabe MinimumKosten;

}

int main()

{

    int Knoten, Kanten, x, y;

    lang lang Gewicht, minimale Kosten;

    cin >> Knoten >> Kanten;

    für(int i = 0;i < Kanten;++i)

    {

        cin >> x >> y >> Gewicht;

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

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

    }

    // Auswahl von 1 als Startknoten

    minimumKosten = prim(1);

    cout << minimale Kosten <<< endl;

    0 zurückgeben;

}