【无标题】

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

// 最小生成树 - Prim算法
int primMST(vector<vector<int>> &graph)
{
    int V = graph.size();
    vector<int> key(V, INT_MAX);  // 顶点的键值,表示到该顶点的最小权值
    vector<bool> inMST(V, false); // 是否在最小生成树中
    int totalWeight = 0;          // 最小生成树的总权值

    // 从第一个顶点开始
    key[0] = 0;

    for (int count = 0; count < V - 1; ++count)
    {
        int u = -1;

        // 选择不在最小生成树中的键值最小的顶点
        for (int v = 0; v < V; ++v)
        {
            if (!inMST[v] && (u == -1 || key[v] < key[u]))
                u = v;
        }

        cout << "primMST当前u :  " << u << endl;
        inMST[u] = true; // 将选定的顶点加入最小生成树

        // 更新与u相邻的顶点的键值
        for (int v = 0; v < V; ++v)
        {
            if (graph[u][v] && !inMST[v] && graph[u][v] < key[v])
            {
                key[v] = graph[u][v];
                cout << "primMST当前key[v]  :  " << key[v] << endl;
            }
        }
    }

    // 计算总权值
    for (int i = 0; i < V; ++i)
        totalWeight += key[i];

    return totalWeight;
}

// 最小生成树 - Kruskal算法
class Kruskal
{
private:
    vector<int> parent;
    int V;

public:
    Kruskal(int vertices) : V(vertices)
    {
        parent.resize(V);
        iota(parent.begin(), parent.end(), 0);
    }

    // 查找顶点的根节点
    int find(int v)
    {
        if (v == parent[v])
            return v;
        return parent[v] = find(parent[v]);
    }

    // 合并两个集合
    void unionSets(int a, int b)
    {
        a = find(a);
        b = find(b);
        if (a != b)
            parent[b] = a;
    }

    // 计算最小生成树的权值
    int kruskalMST(vector<pair<int, pair<int, int>>> &edges)
    {
        sort(edges.begin(), edges.end());
        int mstWeight = 0;

        for (auto edge : edges)
        {
            int u = edge.second.first;
            int v = edge.second.second;
            int weight = edge.first;

            if (find(u) != find(v))
            {
                mstWeight += weight;
                unionSets(u, v);
            }
        }

        return mstWeight;
    }
};

// 最短路径 - Dijkstra算法
void dijkstra(vector<vector<int>> &graph, int src)
{
    int V = graph.size();
    vector<int> dist(V, INT_MAX);
    vector<bool> visited(V, false);

    dist[src] = 0;

    for (int count = 0; count < V - 1; ++count)
    {
        int u = -1;

        for (int v = 0; v < V; ++v)
        {
            if (!visited[v] && (u == -1 || dist[v] < dist[u]))
                u = v;
        }

        visited[u] = true;

        for (int v = 0; v < V; ++v)
        {
            if (!visited[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
                dist[v] = dist[u] + graph[u][v];
        }
    }

    cout << "Dijkstra算法 - 从源点 " << src << " 到各顶点的最短路径长度:" << endl;
    for (int i = 0; i < V; ++i)
        cout << "到顶点 " << i << " 的距离为 " << dist[i] << endl;
}

// 最短路径 - Bellman-Ford算法
void bellmanFord(vector<vector<int>> &graph, int src)
{
    int V = graph.size();
    vector<int> dist(V, INT_MAX);
    dist[src] = 0;

    // 对所有边进行V-1次松弛操作
    for (int i = 0; i < V - 1; ++i)
    {
        for (int u = 0; u < V; ++u)
        {
            for (int v = 0; v < V; ++v)
            {
                if (graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
                    dist[v] = dist[u] + graph[u][v];
            }
        }
    }

    // 检测负权回路
    for (int u = 0; u < V; ++u)
    {
        for (int v = 0; v < V; ++v)
        {
            if (graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v])
            {
                cout << "图中含有负权回路,无法求解最短路径。" << endl;
                return;
            }
        }
    }

    cout << "Bellman-Ford算法 - 从源点 " << src << " 到各顶点的最短路径长度:" << endl;
    for (int i = 0; i < V; ++i)
        cout << "到顶点 " << i << " 的距离为 " << dist[i] << endl;
}

// 最短路径 - Floyd算法
void floydWarshall(vector<vector<int>> &graph)
{
    int V = graph.size();
    vector<vector<int>> dist(graph);

    // 逐个顶点作为中间节点,更新所有顶点对之间的最短路径
    for (int k = 0; k < V; ++k)
    {
        for (int i = 0; i < V; ++i)
        {
            for (int j = 0; j < V; ++j)
            {
                if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][k] + dist[k][j] < dist[i][j])
                    dist[i][j] = dist[i][k] + dist[k][j];
            }
        }
    }

    cout << "Floyd算法 - 所有顶点对之间的最短路径长度:" << endl;
    for (int i = 0; i < V; ++i)
    {
        for (int j = 0; j < V; ++j)
        {
            if (dist[i][j] == INT_MAX)
                cout << "INT_MAX\t";
            else
                cout << dist[i][j] << "\t";
        }
        cout << endl;
    }
}

int main()
{
    // 最小生成树 - Prim算法
    vector<vector<int>> primGraph = {
        {0, 6, 1, 5, 0, 0},
        {6, 0, 5, 0, 3, 0},
        {1, 5, 0, 5, 6, 4},
        {5, 0, 5, 0, 0, 2},
        {0, 3, 6, 0, 0, 6},
        {0, 0, 4, 2, 6, 0}
    };
    
    int primWeight = primMST(primGraph);
    cout << "Prim算法 - 最小生成树的权值为: " << primWeight << endl;

    // 最小生成树 - Kruskal算法
    vector<pair<int, pair<int, int>>> kruskalEdges = {
        {6, {0, 1}},
        {1, {0, 2}},
        {5, {0, 3}},
        {5, {1, 2}},
        {3, {1, 4}},
        {5, {2, 3}},
        {6, {2, 4}},
        {4, {2, 5}},
        {2, {3, 5}},
        {6, {4, 5}},
    };
    Kruskal kruskal(6);
    int kruskalWeight = kruskal.kruskalMST(kruskalEdges);
    cout << "Kruskal算法 - 最小生成树的权值为: " << kruskalWeight << endl;

    // 最短路径 - Dijkstra算法
    vector<vector<int>> dijkstraGraph1 = {
        {0, 4, 0, 0, 0, 0, 0, 8, 0},
        {4, 0, 8, 0, 0, 0, 0, 11, 0},
        {0, 8, 0, 7, 0, 4, 0, 0, 2},
        {0, 0, 7, 0, 9, 14, 0, 0, 0},
        {0, 0, 0, 9, 0, 10, 0, 0, 0},
        {0, 0, 4, 14, 10, 0, 2, 0, 0},
        {0, 0, 0, 0, 0, 2, 0, 1, 6},
        {8, 11, 0, 0, 0, 0, 1, 0, 7},
        {0, 0, 2, 0, 0, 0, 6, 7, 0}
    };

    vector<vector<int>> dijkstraGraph = {
        {0, 10, 0, 0, 5},
        {0, 0, 1, 0, 0},
        {0, 0, 0, 4, 0},
        {7, 0, 6, 0, 0},
        {0, 3, 9, 2, 0},
    };
    cout << " " << endl;
    dijkstra(dijkstraGraph, 0);

    // 最短路径 - Bellman-Ford算法
    vector<vector<int>> bellmanFordGraph1 = {
        {0, 4, 0, 0, 0, 0, 0, 8, 0},
        {4, 0, 8, 0, 0, 0, 0, 11, 0},
        {0, 8, 0, 7, 0, 4, 0, 0, 2},
        {0, 0, 7, 0, 9, 14, 0, 0, 0},
        {0, 0, 0, 9, 0, 10, 0, 0, 0},
        {0, 0, 4, 14, 10, 0, 2, 0, 0},
        {0, 0, 0, 0, 0, 2, 0, 1, 6},
        {8, 11, 0, 0, 0, 0, 1, 0, 7},
        {0, 0, 2, 0, 0, 0, 6, 7, 0}
    };

    vector<vector<int>> bellmanFordGraph = {
        {0, 10, 0, 0, 5},
        {0, 0, 1, 0, 0},
        {0, 0, 0, 4, 0},
        {7, 0, 6, 0, 0},
        {0, 3, 9, 2, 0},
    };
    cout << " " << endl;
    bellmanFord(bellmanFordGraph, 0);

    // 最短路径 - Floyd算法
    vector<vector<int>> floydGraph = {
        {0, 4, INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, 8, INT_MAX},
        {4, 0, 8, INT_MAX, INT_MAX, INT_MAX, INT_MAX, 11, INT_MAX},
        {INT_MAX, 8, 0, 7, INT_MAX, 4, INT_MAX, INT_MAX, 2},
        {INT_MAX, INT_MAX, 7, 0, 9, 14, INT_MAX, INT_MAX, INT_MAX},
        {INT_MAX, INT_MAX, INT_MAX, 9, 0, 10, INT_MAX, INT_MAX, INT_MAX},
        {INT_MAX, INT_MAX, 4, 14, 10, 0, 2, INT_MAX, INT_MAX},
        {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX, 2, 0, 1, 6},
        {8, 11, INT_MAX, INT_MAX, INT_MAX, INT_MAX, 1, 0, 7},
        {INT_MAX, INT_MAX, 2, INT_MAX, INT_MAX, INT_MAX, 6, 7, 0}
    };

    vector<vector<int>> floydGraph1 = {
        {0, 10, INT_MAX, INT_MAX, 5},
        {INT_MAX, 0, 1, INT_MAX, INT_MAX},
        {INT_MAX, INT_MAX, 0, 4, INT_MAX},
        {7, INT_MAX, 6, 0, INT_MAX},
        {INT_MAX, 3, 9, 2, 0},
    };
    cout << " " << endl;
    floydWarshall(floydGraph1);

    return 0;
}

你可能感兴趣的:(算法)