进阶算法(二) 《算法笔记》自定义实现 1、创建、遍历、图 2、DFS及BFS优先搜索 3、最短路径优先(迪杰斯特拉)算法 4、全源最短路径(弗洛伊德)算法 5、最小生成树prim算法 克鲁斯卡尔算法

文章展示了图的邻接矩阵存储方式,并提供了创建图、深度优先搜索(DFS)、广度优先搜索(BFS)的C++代码实现。接着讨论了最短路径问题,给出了迪杰斯特拉算法的自定义实现以及全源最短路径的弗洛伊德算法。最后,探讨了最小生成树的概念,提到了普里姆算法和克鲁斯卡尔算法的基本思想。
摘要由CSDN通过智能技术生成

1、图-邻接矩阵

#include <cstdio>
#include <iostream>
// 图的顺序存储
// 邻接矩阵
#define MAXSIZE 100
struct Graph
{
    char Vertex[MAXSIZE];       // 顶点集
    int Edge[MAXSIZE][MAXSIZE]; // 边集
    int cur_v;                  // 现有顶点数目
    int cur_e;                  // 现有边数目
};
// 建立图
void Create(Graph &G)
{
    int i, j, num;
    std::cout << "输入顶点的个数:\n";
    scanf("%d", &num);
    G.cur_v = num;
    G.cur_e = 0;
    std::cout << "输入顶点的值:\n";
    for (i = 0; i < num; ++i)
        std::cin >> G.Vertex[i];
    printf("输入邻接矩阵:\n");
    for (i = 0; i < num; ++i)
    {
        std::cout << "第" << i + 1 << "行: ";
        for (j = 0; j < num; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != 0)
                ++G.cur_e;
        }
    }

    return;
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    printf("顶点: ");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n边: \n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
        printf("\n");
    }

    return 0;
}

1、图-邻接表

#include <cstdio>
#include <iostream>
#include <vector>
// 图G = (V, {E}); 顶点集 边集
// 邻接表表示该顶点与哪几个顶点之间有边 链表 动态数组
struct Vertex
{
    char val; // 顶点的值
    std::vector<int> edge; // 该顶点与哪几个顶点有边 // 方便尾插

};
// 图
typedef struct Graph
{
    std::vector<Vertex> v;
};

int main()
{

    return 0;
}

2、DFS深度优先搜索 

#include <cstdio>
#include <iostream>
// 图的顺序存储
// 邻接矩阵
#define MAXSIZE 100
struct Graph
{
    char Vertex[MAXSIZE];       // 顶点集
    int Edge[MAXSIZE][MAXSIZE]; // 边集
    int cur_v;                  // 现有顶点数目
    int cur_e;                  // 现有边数目
};
// 建立图
void Create(Graph &G)
{
    int i, j, num;
    std::cout << "输入顶点的个数:\n";
    scanf("%d", &num);
    G.cur_v = num;
    G.cur_e = 0;
    std::cout << "输入顶点的值:\n";
    for (i = 0; i < num; ++i)
        std::cin >> G.Vertex[i];
    printf("输入邻接矩阵:\n");
    for (i = 0; i < num; ++i)
    {
        std::cout << "第" << i + 1 << "行: ";
        for (j = 0; j < num; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != 0)
                ++G.cur_e;
        }
    }

    return;
}
int visited[MAXSIZE] = {0};
// 深度优先搜索DFS
void DFS(Graph G, int v)
{
    // 一条路走到底, 不行就返回上一个位置(返给调用者-上一层递归函数)
    // 从v顶点出发, 辅助数组中该顶点的位置 = 1(访问过了该顶点)
    // 查询邻接矩阵第v行(第一个非0元素)且未被访问过
    // 从该顶点出发
    visited[v] = 1;             // 辅助数组中该顶点的位置=1
    printf("%c ", G.Vertex[v]); // 输出该顶点
    for (int i = 0; i < G.cur_v; ++i)
    {
        if (G.Edge[v][i] != 0 && visited[i] != 1) // 邻接矩阵第v行第1个非0元素且未被访问过
            DFS(G, i);                            // 从该顶点出发
    }
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    printf("顶点: ");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n边: \n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
        printf("\n");
    }
    printf("深度优先搜索: ");
    DFS(G, 0);
    printf("\n");

    return 0;
}

2、BFS广度优先搜索 

#include <cstdio>
#include <iostream>
#include <queue>
// 图的顺序存储
// 邻接矩阵
#define MAXSIZE 100
struct Graph
{
    char Vertex[MAXSIZE];       // 顶点集
    int Edge[MAXSIZE][MAXSIZE]; // 边集
    int cur_v;                  // 现有顶点数目
    int cur_e;                  // 现有边数目
};
// 建立图
void Create(Graph &G)
{
    int i, j, num;
    std::cout << "输入顶点的个数:\n";
    scanf("%d", &num);
    G.cur_v = num;
    G.cur_e = 0;
    std::cout << "输入顶点的值:\n";
    for (i = 0; i < num; ++i)
        std::cin >> G.Vertex[i];
    printf("输入邻接矩阵:\n");
    for (i = 0; i < num; ++i)
    {
        std::cout << "第" << i + 1 << "行: ";
        for (j = 0; j < num; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != 0)
                ++G.cur_e;
        }
    }

    return;
}
// 广度优先搜索BFS
int visited[MAXSIZE] = {0};
void BFS(Graph G, int v)
{
    // v顶点入队
    // 访问队头元素 队头出队 原队头的邻接点(查询临接矩阵)入队
    // 队列空 结束
    int i, tmp;
    std::queue<int> q;
    q.push(v);
    visited[v] = 1;
    while (!q.empty())
    {
        tmp = q.front();
        printf("%c ", G.Vertex[tmp]); // 访问队头元素
        q.pop();                      // 队头元素出队
        for (i = 0; i < G.cur_e; ++i) // 查询邻接矩阵第tmp行
        {
            if (G.Edge[tmp][i] != 0 && visited[i] != 1) // 该顶点的(未被访问的/未在队列的)邻接点入队
            {
                q.push(i);
                visited[i] = 1; // 辅助数组的该顶点的位置 = 1
            }
        }
    }
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    printf("顶点: ");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n边: \n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
        printf("\n");
    }
    printf("广度优先搜索: ");
    BFS(G, 0);
    printf("\n");

    return 0;
}

3、最短路径 迪杰斯特拉算法 自定义实现

#include <cstdio>
#include <iostream>
#include <vector>
// 图的顺序存储
// 邻接矩阵
#define MAXSIZE 100
struct Graph
{
    char Vertex[MAXSIZE];       // 顶点集
    int Edge[MAXSIZE][MAXSIZE]; // 边集
    int cur_v;                  // 现有顶点数目
    int cur_e;                  // 现有边数目
};
// 建立图
void Create(Graph &G)
{
    int i, j, num;
    std::cout << "输入顶点的个数:\n";
    scanf("%d", &num);
    G.cur_v = num;
    G.cur_e = 0;
    std::cout << "输入顶点的值:\n";
    for (i = 0; i < num; ++i)
        std::cin >> G.Vertex[i];
    printf("输入邻接矩阵:\n");
    for (i = 0; i < num; ++i)
    {
        std::cout << "第" << i + 1 << "行: ";
        for (j = 0; j < num; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != 0)
                ++G.cur_e;
        }
    }

    return;
}
int visited[MAXSIZE] = {0}; // 设置辅助数组--顶点加入S 判断V-S中没顶点
// 计算从某个顶点(源点)出发到其他各个顶点的最短路径(经过的所有边权值的和)
void Djstl(Graph G, int ShortestPath[], int n, int start)
{
    // 输入从(源点)起点到其他顶点的最短直达路径长度表
    // n个顶点进行n-1轮, 每一轮挑选1个顶点作为中转点更新最短路径长度表
    int i, j, Min, Minloc;
    std::vector<int>::iterator p, tmp; // 用来遍历VS, 选择顶点
    // 1、初始化
    std::vector<int> S;
    S.push_back(start); // 源点加入集合S
    std::vector<int> VS;
    for (i = 0; i < n; ++i)
    {
        if (i != start)
            VS.push_back(i); // 剩余顶点加入集合VS;
        else
            continue;
    }
    // 2、开始n-1轮挑选和更新最短路径长度表
    for (i = 1; i < n; ++i)
    {
        // 3、每一轮从V-S集合中挑出1个顶点(距离源点最短(Shortest[]最小))加入S
        Min = ShortestPath[*VS.begin()];
        Minloc = *VS.begin();
        tmp = VS.begin(); // 用来V_S中释放该顶点
        for (p = VS.begin(); p != VS.end(); ++p)
        {
            if (ShortestPath[*p] < Min)
            {
                Min = ShortestPath[*p]; // 更新最小值
                Minloc = *p;            // 更新最小值的位置
                tmp = p;                // 找到该顶点了
            }
        }
        S.push_back(*tmp); // 该顶点加入S
        VS.erase(tmp);     // VS删除该顶点
        // 4、以该顶点为中转更新最短路径长度表
        for (int j = 0; j < n; ++j)
        {
            if (G.Edge[start][Minloc] + G.Edge[Minloc][j] < ShortestPath[j])
                ShortestPath[j] = G.Edge[start][Minloc] + G.Edge[Minloc][j];
        }
    }
    return;
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    printf("验证创建图: \n");
    printf("顶点: ");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n边: \n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
        printf("\n");
    }
    printf("迪杰斯特拉算法:\n");
    int Shortest[6] = {0, 1, 65535, 4, 4, 65535};
    for (i = 0; i < 6; ++i)
        printf("%d ", Shortest[i]);
    printf("\n");
    Djstl(G, Shortest, 6, 0);
    printf("迪杰斯特拉算法:\n");
    for (i = 0; i < 6; ++i)
        printf("%d ", Shortest[i]);
    printf("\n");

    return 0;
}

3最短路径 迪杰斯特拉

#include <cstdio>
#include <iostream>
#include <algorithm>
#define INF 65535
// 图
#define MAXSIZE 1000
struct Graph
{
    char Vertex[MAXSIZE];
    int Edge[MAXSIZE][MAXSIZE];
    int cur_v; // 现有顶点数
    int cur_e; // 现有总边数
};
// 初始化图
void Create(Graph & G)
{
    int i, j, n;
    std::cout << "顶点的个数:\n";
    std::cin >> n;
    G.cur_v = n;
    G.cur_e = 0;
    std::cout << "顶点集:\n";
    for (i = 0; i < n; ++i)
        std::cin >> G.Vertex[i];
    std::cout << "边的邻接矩阵:\n";
    for (i = 0; i < n; ++i)
    {
        std::cout << "第" << i + 1 << "行: "; 
        for (j = 0; j < n; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != INF)
                ++G.cur_e;
        }
    }

    return ;
}
// 迪杰斯特拉算法一样--计算从起点到其余顶点的最短路径长度
// 假设从0号顶点出发--到其他顶点的最短路径长度表
int visited[MAXSIZE]; // 辅助数组
int distance[MAXSIZE]; // i顶点(起点)到其他顶点的最短路径长度表
void Dijkstra(Graph G)
{
    std::cout << "初始化\n";
    // 初始化
    std::fill(distance, distance + MAXSIZE, INF); //从i顶点(源点)到其他顶点最短路径长度表
    distance[0] = 0; // 假定从0号顶点出发
    std::fill(visited, visited + MAXSIZE, 0); // 辅助数组
    std::cout << "初始化结束\n";
    // n个顶点n轮挑选--不设置集合S V-S
    for (int i = 0; i < G.cur_v; ++i)
    {
        printf("第%d轮挑选\n", i + 1);
        // 1、挑选顶点(距离源点最近)
        int Minloc = -1, Min = INF;
        for (int j = 0; j < G.cur_v; ++j)
        {
            if (visited[j] == 0 && distance[j] < Min)  
            {
                Min = distance[j];
                Minloc = j;
            }  
        }
        printf("挑中了%d顶点\n", Minloc);
        if (Minloc == -1)
            return ; // 没找到
        // 2、以该顶点为中转点更新最短路径长度表
        visited[Minloc] = 1; // 找到了距离源点距离最短的顶点
        printf("第%d轮更新:\n", i + 1);
        for (int k = 0; k < G.cur_v; ++k)
        {
            // 起点-中转点-中转点--没必要更新
            // 起点-中转点-其他某个顶点 (中转点-其他顶点 没有边到达--没必要更新)
            if (visited[k] == 0 && G.Edge[Minloc][k] != INF && distance[Minloc] + G.Edge[Minloc][k] < distance[k])
            {
                distance[k] =  distance[Minloc] + G.Edge[Minloc][k];
            }
        }
        printf("最短路径长度表: ");
        for (int m = 0; m < G.cur_v; ++m)
            printf("%d ", distance[m]);
        printf("\n");
        printf("第%d轮更新结束\n", i + 1);
    }
    return ; 
}
// 输出图
void Show(Graph G)
{
    int i, j;
    std::cout << "顶点个数: " << G.cur_v << " 边数: " << G.cur_e << "\n";
    std::cout << "顶点信息:\n";
    for (i = 0; i < G.cur_v; ++i)
        std::cout << G.Vertex[i] << " ";
    std::cout << "\n边的信息:\n";
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
        {
            std::cout << G.Edge[i][j] << " ";
        }
        std::cout << std::endl;
    }
    return ;
}

int main()
{
    Graph G;
    Create(G);
    Show(G);
    Dijkstra(G);

    return 0;
}

3、全源最短路径 弗洛伊德 

#include <cstdio>
#include <iostream>
#include <vector>
// 图G = (V, E); 顶点集 边集
#define MAXSIZE 100
struct Graph
{
    char Vertex[MAXSIZE];       // 顶点集
    int Edge[MAXSIZE][MAXSIZE]; // 边集
    int cur_v;                  // 现有顶点数
    int cur_e;                  // 现有边的数
};
// 初始化图
void Create(Graph &G)
{
    int i, j, num;
    std::cout << "顶点的个数: ";
    std::cin >> num;
    G.cur_v = num;
    G.cur_e = 0;
    std::cout << "顶点的值: ";
    for (i = 0; i < num; ++i)
        std::cin >> G.Vertex[i];
    std::cout << "边集:\n";
    for (i = 0; i < num; ++i)
    {
        std::cout << "第" << i + 1 << "行: ";
        for (j = 0; j < num; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != 65535) // 65535代表i j顶点之间没有边
                ++G.cur_e;
        }
    }
    return;
}
// 输出图
void Show(Graph G)
{
    int i, j;
    printf("顶点集:\n");
    for (i = 0; i < G.cur_v; ++i)
        printf("%c ", G.Vertex[i]);
    printf("\n边集:\n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", G.Edge[i][j]);
        printf("\n");
    }
    return;
}
// 弗洛伊德算法--全源最短路径--求图中任意2顶点之间的最短路径长度(经过所有的边的权的和)
// 执行n轮迪杰斯特拉算法
int Shortest[6][6] =
    {{0, 1, 65535, 4, 4, 65535}, {65535, 0, 65535, 2, 65535, 65535}, {65535, 65535, 0, 65535, 65535, 1}, {65535, 65535, 2, 0, 3, 65535}, {65535, 65535, 65535, 65535, 0, 3}, {65535, 65535, 65535, 65535, 65535, 0}};
// 最短路径长度Shortest[i][]; // 从i顶点到其他顶点的最短路径长度
void Floyd(Graph &G, int Shortest[][6], int n = 6)
{
    // 任意2个顶点的最短路径长度
    int i, j, k, Min, Minloc;
    std::vector<int>::iterator p, tmp; // 用来遍历VS, 选择顶点
    for (i = 0; i < n; ++i)            // n轮更新最短路径长度表
    {
        // 输入从(源点)起点到其他顶点的最短直达路径长度表
        // n个顶点进行n-1轮, 每一轮挑选1个顶点作为中转点更新最短路径长度表
        // 1、初始化
        std::vector<int> S;
        S.push_back(i); // 源点加入集合S
        std::vector<int> VS;
        for (j = 0; j < n; ++j)
        {
            if (j != i)
                VS.push_back(j); // 剩余顶点加入集合VS;
            else
                continue;
        }
        // 2、开始n-1轮挑选和更新最短路径长度表
        for (j = 1; j < n; ++j)
        {
            // 3、每一轮从V-S集合中挑出1个顶点(距离源点最短(Shortest[]最小))加入S
            Min = Shortest[i][*VS.begin()];
            Minloc = *VS.begin();
            tmp = VS.begin(); // 用来V_S中释放该顶点
            for (p = VS.begin(); p != VS.end(); ++p)
            {
                if (Shortest[i][*p] < Min)
                {
                    Min = Shortest[i][*p]; // 更新最小值
                    Minloc = *p;            // 更新最小值的位置
                    tmp = p;                // 找到该顶点了
                }
            }
            S.push_back(*tmp); // 该顶点加入S
            VS.erase(tmp);     // VS删除该顶点
            // 4、以该顶点为中转更新最短路径长度表
            for (k = 0; k < n; ++k)
            {
                if (G.Edge[i][Minloc] + G.Edge[Minloc][k] < Shortest[i][k])
                    Shortest[i][k] = G.Edge[i][Minloc] + G.Edge[Minloc][k];
            }
        }
    }
    return;
}

int main()
{
    int i, j;
    Graph G;
    Create(G);
    Show(G);
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", Shortest[i][j]);
        printf("\n");
    }
    printf("弗洛伊德算法:\n");
    Floyd(G, Shortest);
    printf("全源最短路径长度:\n");
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
            printf("%d ", Shortest[i][j]);
        printf("\n");
    }

    return 0;
}

4、最小生成树 prim算法 

#include <cstdio>
#include <iostream>
#include <algorithm>
#define INF 65535
// 图
#define MAXSIZE 1000
struct Graph
{
    char Vertex[MAXSIZE];
    int Edge[MAXSIZE][MAXSIZE];
    int cur_v; // 现有顶点数
    int cur_e; // 现有总边数
};
// 初始化图
void Create(Graph & G)
{
    int i, j, n;
    std::cout << "顶点的个数:\n";
    std::cin >> n;
    G.cur_v = n;
    G.cur_e = 0;
    std::cout << "顶点集:\n";
    for (i = 0; i < n; ++i)
        std::cin >> G.Vertex[i];
    std::cout << "边的邻接矩阵:\n";
    for (i = 0; i < n; ++i)
    {
        std::cout << "第" << i + 1 << "行: "; 
        for (j = 0; j < n; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != INF)
                ++G.cur_e;
        }
    }

    return ;
}
// 最小生成树---n顶点n-1条边的权和最小
// 普里姆算法和迪杰斯特拉算法类似
// 0、初始化S = {0}, V-S = {1, 2, 3, 4, 5}; //顶点代号
// 1、从V-S集合中挑选出1个顶点 (该顶点距离S集合距离最小), 该顶点加入S集合
// 2、该顶点到V-S的边加入边集distance[MAXSIZE] 更新边集(V-S中的剩余顶点到S集合的最短距离);
// 直到S = {0, 1, 2, 3, 4, 5, 6}; (S, distance)最小生成树
int visited[MAXSIZE]; // 辅助数组
int distance[MAXSIZE]; // 边集(选中的边)
int Prim(Graph G)
{
    std::cout << "初始化\n";
    // 初始化
    std::fill(distance, distance + MAXSIZE, INF); //从i顶点(源点)到其他顶点最短路径长度表
    distance[0] = 0; // 假定从0号顶点出发
    std::fill(visited, visited + MAXSIZE, 0); // 辅助数组
    int sum = 0; // 最小生成树的边权之和
    std::cout << "初始化结束\n";
    // n个顶点n轮挑选--不设置集合S V-S
    for (int i = 0; i < G.cur_v; ++i)
    {
        printf("第%d轮挑选\n", i + 1);
        // 1、挑选顶点(距离S集合最近)
        int Minloc = -1, Min = INF;
        for (int j = 0; j < G.cur_v; ++j)
        {
            if (visited[j] == 0 && distance[j] < Min)  
            {
                Min = distance[j];
                Minloc = j;
            }  
        }
        printf("挑中了%d顶点\n", Minloc);
        if (Minloc == -1)
            return -1; // 没找到
        // 2、该顶点加入S 该顶点到S集合的边加入边集distance[]
        visited[Minloc] = 1; // 找到了距离S集合距离最短的顶点
        sum += distance[Minloc]; // 选中的该边加入
        printf("第%d轮更新选中的边集:\n", i + 1);
        for (int k = 0; k < G.cur_v; ++k)
        {
            // 选中的顶点-S集合--没必要更新
            // 其他某个顶点-选中的顶点 (其他顶点-选中的顶点 没有边到达--没必要更新)
            // 更新其他顶点(V-S集合中的)到S集合的最短距离
            if (visited[k] == 0 && G.Edge[Minloc][k] != INF && G.Edge[Minloc][k] < distance[k])
            {
                distance[k] =  G.Edge[Minloc][k];
            }
        }
        printf("选中的边: ");
        for (int m = 0; m < G.cur_v; ++m)
            printf("%d ", distance[m]);
        printf("\n");
        printf("第%d轮更新选中的边集结束\n", i + 1);
    }
    return sum;
}
// 输出图
void Show(Graph G)
{
    int i, j;
    std::cout << "顶点个数: " << G.cur_v << " 边数: " << G.cur_e << "\n";
    std::cout << "顶点信息:\n";
    for (i = 0; i < G.cur_v; ++i)
        std::cout << G.Vertex[i] << " ";
    std::cout << "\n边的信息:\n";
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
        {
            std::cout << G.Edge[i][j] << " ";
        }
        std::cout << std::endl;
    }
    return ;
}

int main()
{
    Graph G;
    Create(G);
    Show(G);
    int all = Prim(G);
    std::cout << "all = " << all << "\n";   

    return 0;
}

5、最小生成树 克鲁斯卡尔算法 

#include <cstdio>
#include <iostream>
#include <algorithm>
#define INF 65535
// 图
#define MAXSIZE 1000
struct Graph
{
    char Vertex[MAXSIZE];
    int Edge[MAXSIZE][MAXSIZE];
    int cur_v; // 现有顶点数
    int cur_e; // 现有总边数
};
// 初始化图
void Create(Graph & G)
{
    int i, j, n;
    std::cout << "顶点的个数:\n";
    std::cin >> n;
    G.cur_v = n;
    G.cur_e = 0;
    std::cout << "顶点集:\n";
    for (i = 0; i < n; ++i)
        std::cin >> G.Vertex[i];
    std::cout << "边的邻接矩阵:\n";
    for (i = 0; i < n; ++i)
    {
        std::cout << "第" << i + 1 << "行: "; 
        for (j = 0; j < n; ++j)
        {
            std::cin >> G.Edge[i][j];
            if (G.Edge[i][j] != INF)
                ++G.cur_e;
        }
    }

    return ;
}
// 最小生成树---n顶点n-1条边的权和最小
// 克鲁斯卡尔算法--边贪心-
// 1、每一轮选择权最小的边
// 2、判断加入该边是否形成环---成环-弃掉该边 不成环-加入边集
// 直到选中了n-1条边-结束
int Kruskal(Graph G)
{
    // 难? 判断加入该边后图是否成环? 
    // 该边的两个顶点在不同集合内S V-S--才不会成环
    // 该边的两个顶点在同集合S 成环---引入并查集
}

// 输出图
void Show(Graph G)
{
    int i, j;
    std::cout << "顶点个数: " << G.cur_v << " 边数: " << G.cur_e << "\n";
    std::cout << "顶点信息:\n";
    for (i = 0; i < G.cur_v; ++i)
        std::cout << G.Vertex[i] << " ";
    std::cout << "\n边的信息:\n";
    for (i = 0; i < G.cur_v; ++i)
    {
        for (j = 0; j < G.cur_v; ++j)
        {
            std::cout << G.Edge[i][j] << " ";
        }
        std::cout << std::endl;
    }
    return ;
}

int main()
{
    Graph G;
    Create(G);
    Show(G);
    

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪呈祥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值