邻接表的最小生成树

#include <iostream>//邻接表的最小生成树
#include <cstring>
#include <vector>
#include <cstdio>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
struct node{
    int to,num;
};
vector<node>v[1010];
int prim(){
    node d;
    int visit[1010];
    int len[1010];
    int sum=0;
    int mini,u;
    memset(visit,0,sizeof(visit));
    memset(len,INF,sizeof(INF));
    visit[1]=1;
    for(int i=0;i<v[1].size();i++){
        d=v[1][i];
        len[d.to]=d.num;
    }
    len[1]=0;
    for(int j=1;j<n;j++){
        mini=INF;
        for(int i=1;i<=n;i++){
            if(!visit[i]&&len[i]<mini){
                mini=len[i];
                u=i;
            }
        }
        sum+=len[u];
        visit[u]=1;
        for(int i=0;i<v[u].size();i++){
            d=v[u][i];
            if(!visit[d.to]&&len[d.to]>d.num){
                len[d.to]=d.num;
            }
        }
    }
    return sum;
}
int main(){
    cin.sync_with_stdio(false);
    int a,b,c;
    while(cin>>n>>m){
        for(int i=1;i<=n;i++){
            v[i].clear();
        }
        for(int i=0;i<m;i++){
            cin>>a>>b>>c;
            node d;
            d.to=b;
            d.num=c;
            v[a].push_back(d);
            d.to=a;
            v[b].push_back(d);
        }
        cout<<prim()<<endl;
    }
    return 0;
}

对任意给定的(顶点数不小于20,数不少于30,的类型可以是有向、无向、有向网、无向网),能够输入的顶点和(或弧)的信息,并存储到相应存储结构(邻接矩阵、邻接表、十字链表、邻接多重表,任选其中两种类型),对自己所创建完成以下操作: 1、 对无向求每个顶点的度,或对有向求每个顶点的入度和出度(5分) 2、 完成插入顶点和(或弧)的功能(5分) 3、 完成删除顶点和(或弧)的功能(5分) 4、 两种存储结构的转换(5分),如果其中一种存储结构为十字链表或邻接多重表则增加5分。 5、 输出的深度优先遍历序列或广度优先遍历序列(5分) 6、 求的深度优先或广度优先的生成树(或生成森林)(存储结构为孩子-兄弟链表),并对生成树进行遍历(15分) 7、 判断的连通性,输出连通分量的个数(5分) 8、 判断中是否存在环,无向5分,有向10分 9、 给出顶点u和v,判断u到v是否存在路径(5分) 10、求顶点u到v的一条简单路径(10分) 11、求顶点u到v的所有简单路径(15分) 12、求顶点u到v的最短路径(10分) 13、求顶点u到其余各顶点的最短路径(15分) 14、求任两个顶点之间的最短路径(15分) 15、求最小生成树(15分) 16、对于有一个源点和一个汇点的有向网,求关键路径(20分)
### C++ 实现基于链式邻接表表示法的最小生成树 为了实现基于链式邻接表表示法的最小生成树(MST),可以采用 Kruskal 或 Prim 算法。这里展示一种利用 Prim 算法的方式,该方法通过优先队列来优化的选择过程。 #### 邻接表定义 首先定义的数据结构,使用链式存储方式: ```cpp #include <vector> #include <queue> #include <climits> struct Edge { int dest; int weight; }; class Graph { public: explicit Graph(int V); void addEdge(int src, int dest, int weight); private: std::vector<std::list<Edge>> adjList; }; ``` 此部分代码创建了一个 `Graph` 类,其中包含了添加的方法以及内部使用的邻接列表 `adjList`[^1]。 #### Prim 算法实现 接下来是具体的 MST 计算逻辑: ```cpp void primMST(Graph& graph) { int V = graph.adjList.size(); std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, std::greater<>> pq; std::vector<bool> mstSet(V, false); // 跟踪节点是否已加入MST std::vector<int> key(V, INT_MAX); // 存储最短路径权重 std::vector<int> parent(V, -1); // 用于重建最终的MST key[0] = 0; // 初始化起点 pq.push({key[0], 0}); while (!pq.empty()) { auto [weight, u] = pq.top(); pq.pop(); if (mstSet[u]) continue; mstSet[u] = true; for (auto edge : graph.adjList[u]) { int v = edge.dest; if (!mstSet[v] && edge.weight < key[v]) { parent[v] = u; key[v] = edge.weight; pq.push({key[v], v}); } } } // 输出构建好的MST for (int i = 1; i < V; ++i) printf("Edge %d-%d\n", parent[i], i); } ``` 上述程序实现了Prim算法的核心流程,并且采用了二叉堆作为优先级队列以提高效率。对于每一个顶点,当其被纳入到当前生长中的MST时,则更新相邻未访问过的顶点的距离并将其放入优先队列中等待处理[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值