最小スパニングツリー(プリム、クラスカル)

問題の説明
=(V、E)において、(U、V)Tは、として存在する場合、所定のフリーグラフGにおける頂点vに対するuの頂点の連結端部を表しており、このエッジ重みのW(U、V)表現そしてEは、W(T)最小は、この最小G.の木Tをまたがるように、非環式グラフのサブセットであります

ここに画像を挿入説明

ここに画像を挿入説明

(A)クラスカルのアルゴリズム:
側のソート、マージ二組のうちのコレクションの両端開始から貪欲最小側、収集ポイントとして考え各、そうでない場合と同じ側です。コレクションの残りの部分まで、最小スパニングツリーです。

ここに画像を挿入説明
(B)プリム法:
コレクションにこのコレクションから最も近い点を見つけ、セットの始まりのために点をピックします。

ここに画像を挿入説明
設計
[コア擬似コード】
最小スパニングツリー:
()クラスカルのアルゴリズム:
構造Aのアレイを確立する、彼の側と二つの端点を保存; N-
入力し、
配列Aが大きい順にした。logN個の
配列を作成します;各Bは、それ自体に等しく設定し、各セットの要素としてれる
二組、出力側のサイドAを横断する、動作は同じセットに両側性でない場合、または組み合わせ; N-
(II)プリム法:
二次元を確立します図配列Aが格納され、
入力し、
確立されたB配列は0にすべてのビットを設定し、nは
、接続点の第一の側を横断し、最短マークこの点をアレイ状に、点B 1が1に設定され、出力側、<N
サイクル{
IF(Bは、すべて1である)BREAKは、
全ての点を通って、出力側が1に設定されている最近、それらが接続マークされた0点を、1標識;
* N-N- <(N-1-);}

分析
いくつかのケースではクラスカル側は、プリムの効率よりも高くする必要があります

ソース
[GitHubの送信元アドレス]
はありませんGitリポジトリ。

クラスカル:

#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;

struct edge
{
    int a, b, len;
};
int cmp(const void *a, const void *b)
{
    int c = (*(edge *)a).len, d = (*(edge *)b).len;
    return  c-d;
}
  int B[10];
int find(int a){
    return B[a] == a ? a : B[a]=find(B[a]);
}

int main()
{
    ifstream in;
    in.open("input.txt");
    int m, n;
    in >> m >> n;
  
    struct edge A[15];

    //初始化数组
    for (int i = 0; i < m; i++)
    {
        B[i] = i;
    }

    //存图
    for (int i = 0; i < n; i++)
    {
        char a, b;
        int c;
        in >> a >> b >> c;
        a -= 'a';
        b -= 'a';
        A[i].a = a;
        A[i].b = b;
        A[i].len = c;
    }
    qsort(A, n, sizeof(A[0]), cmp);


    for (int i = 0; i < n; i++)
    {
        if (find(A[i].a)!=find(A[i].b)){
            B[find(A[i].b)] = find(A[i].a);
            cout << (char)(A[i].b+'a') << "--" << (char)(A[i].a+'a') << "   " << A[i].len << endl;

        }
        
    }
    in.close();
}

堅苦しい:

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main()
{
    ifstream in;
    in.open("input.txt");
    int A[10][10], m, n, B[10];
    in >> m >> n;
    //初始化数组
    for (int i = 0; i < m; i++)
    {
        B[i] = 0;
        for (int j = 0; j <= i; j++)
        {
            A[i][j] = A[j][i] = INT32_MAX;
        }
    }
    //存图
    for (int i = 0; i < n; i++)
    {
        char a, b;
        int c;
        in >> a >> b >> c;
        a -= 'a';
        b -= 'a';
        A[a][b] = A[b][a] = c;
    }

    //处理第一个点
    int date = INT32_MAX, flag = 0;
    for (int i = 0; i < m; i++)
    {
        if (A[0][i] < date)
        {
            flag = i;
            date = A[0][i];
        }
    }
    cout << 'a' << "--" << (char)(flag + 'a') << "   "<<date << endl;
    B[0] = B[flag] = 1;

    while (1)
    {
        date = INT32_MAX, flag = 0;
        int flag2 = 0;
        int break_date = 0;
        for (int i = 0; i < m; i++)
        {
            if (B[i] == 0)
                break_date = 1;
            else
            {
                for (int j = 0; j < m; j++)
                {
                    if (!B[j])
                    {
                        if (A[i][j] < date)
                        {
                            flag = i;
                            flag2 = j;
                            date = A[i][j];
                        }
                    }
                }
            }
        }
        if (!break_date)
            break;
        B[flag2] = 1;
        cout << (char)(flag + 'a') << "--" << (char)(flag2 + 'a') <<"   "<< date << endl;
    }

    in.close();
}
リリース6元記事 ウォンの賞賛6 ビュー93

おすすめ

転載: blog.csdn.net/qq_45525352/article/details/104644830