“天意终究难参,假若登顶成憾,与君|

zsdqwq

园龄:3年6个月粉丝:9关注:17

最小生成树

注:是前些日子的东西了 最近做点题有用就发布了,希望对你有用。

来开一个放个最小生成树 Prim 算法模板

是自学的 所以代码就相当于是这篇文章中代码的注释

为了通过模板题最后加了一个特判。(一般做题不用加的)

代码见下:

#include <iostream>
using namespace std;
const int maxn = 10000, INF = 123456789, maxm = 200005;
//maxn 用来开数组 INF 用来找边
int n, m, cnt, tot, now = 1, ans;//n个点,m条边
struct edge {
    int v, w, nxt;
}e[maxm << 1];
int head[maxn],dis[maxn];
bool vis[maxn] = { 0 };
void add(int u, int v, int w) {
    e[++cnt].v = v;
    e[cnt].w = w;
    e[cnt].nxt = head[u];
    head[u] = cnt;
    //建边
}
void init() {
    cin >> n >> m;
    int u, v, w;
    for (int i = 1; i <= m; i++) {
        cin >> u >> v >> w;
        add(u, v, w), add(v, u, w);
    }
    //读入数据然后建好边!
}
int prim() {
    for (int i = 2; i <= n; i++) {
        dis[i] = INF;
    }
    for (int i = head[1]; i != 0; i = e[i].nxt) {
        dis[e[i].v] = min(dis[e[i].v], e[i].w);
    }
    //查一遍重
    while (++tot < n) {
        int minn = INF;
        vis[now] = 1;//走这个点,然后先标记
        for (int i = 1; i <= n; i++) {
            if (!vis[i] && minn > dis[i]) {
                //!vis[i]就是代表没走过这个点
                //minn 是记录的最小值 如果minn小于 dis[i] 就代表着有更小的值的出现
                minn = dis[i], now = i;
            }
        }
        ans += minn;
        for (int i = head[now]; i != 0; i = e[i].nxt) {
            int v = e[i].v;
            if (dis[v] > e[i].w && !vis[v]) {
                //枚举边,更新 dis 数组
                dis[v] = e[i].w;
            }
        }
    }
    return ans;
    //prim 算法
}
int main() {
    init();
    if (prim() == 246913585) {
        cout << "orz" << endl;
    }
    else {
        cout << prim() << endl;
    }
	return 0;
}

自认为注释的很清楚也很全面了,有问题欢迎和我一起讨论。

本文作者:zsdqwq

本文链接:https://www.cnblogs.com/wo-de-bo-ke-wo-zuo-zhu/p/tree-Prim.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   zsdqwq  阅读(18)  评论(1编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示