prim算法原理和dijkstra算法差不多,依然不能处理负边

 1 #include<bits/stdc++.h>
2 using namespace std;
3 struct edge
4 {
5 int u,v,w,nxt;
6 };
7 edge e[100010];//建边
8 bool f[110];//判断该点是否被染过色
9 struct node
10 {
11 int dis,t;
12 };
13 node nod[110];//存点
14 int n,cnt,total;// n 点数 cnt 计数器 total 最小生成树的边权和
15 int h[110];//记录每个点发出的最后一条边的编号
16 void add(int,int,int);//函数声明
17 struct cmp
18 {
19 bool operator()(node a,node b)
20 {
21 return a.dis>b.dis;
22 }
23 };//定义比较函数,别忘了';'
24 priority_queue<node,vector<node>,cmp> q;//定义结构体优先队列存点
25 void prim()//堆优化
26 {
27 while(!q.empty()&&cnt<n)//cnt 判断是否达到n-1条边
28 {
29 while(!q.empty()&&f[q.top().t]) q.pop();//判断队首元素是否被标记,若被标记,踢出
30 //加这个的原因是每加一个元素,他不会更新已经在队列中的元素,而是作为新元素加入队列
31 if(q.empty()) break;//如果堆为空,说明都打过标记了,那也就没有继续下去的必要了,退出即可,这里可能会被卡时间
32 node k=q.top();//取队首元素
33 int u=k.t;//取队首元素标号
34 f[u]=1;//打标记
35 total+=nod[u].dis;//记录最小生成树的边权和
36 q.pop();//弹出
37 for(int i=h[u];i;i=e[i].nxt)//邻接表遍历,更新值
38 {
39 int v=e[i].v,w=e[i].w;//取终点和边权
40 if(w<nod[v].dis)//判断边权是否更小
41 {
42 nod[v].dis=w;//更新值
43 q.push(nod[v]);//入队
44 }
45 }
46 cnt++;//记录已经找到了的边的数量
47 }
48 }
49 int main()
50 {
51 scanf("%d",&n);//输入点数
52 for(int i=1;i<=n;++i)
53 {
54 nod[i].dis=0x3f3f3f;//初始化
55 nod[i].t=i;//记录点的标号
56 }
57 for(int i=1;i<=n;++i)
58 {
59 for(int j=1;j<=n;++j)//循环建边,根据题目来
60 {
61 int w;
62 scanf("%d",&w);
63 if(w)
64 {
65 add(i,j,w);//建边
66 add(j,i,w);
67 }
68 }
69 }
70 nod[1].dis=0;//起点到自己的距离是0
71 q.push(nod[1]);//入队
72 cnt=0;//初始化计数器(循环利用)
73 prim();//prim算法
74 printf("%d",total);
75 return 0;//结束
76 }
77 void add(int u,int v,int w)//加边
78 {
79 e[++cnt].u=u;
80 e[cnt].v=v;
81 e[cnt].w=w;
82 e[cnt].nxt=h[u];
83 h[u]=cnt;
84 }

重载运算符版本

 1 #include<bits/stdc++.h>
2 #define ll long long
3 #define rll register long long
4 using namespace std;
5 ll n,m,cnt,tot;
6 ll h[5010];
7 bool flag[5010];
8 struct edge
9 {
10 ll u,v,w,nxt;
11 };
12 edge e[400010];
13 struct node
14 {
15 ll t,dis;
16 bool operator < (const node &b) const
17 {
18 return dis>b.dis;
19 }//重载运算符
20 };
21 node nod[5010];
22 priority_queue<node> q;
23 void add(ll,ll,ll);
24 void prim();
25 int main()
26 {
27 scanf("%lld%lld",&n,&m);
28 for(rll i=1;i<=n;++i)
29 {
30 nod[i].dis=0x3f3f3f;
31 nod[i].t=i;
32 }
33 for(rll u,v,w,i=1;i<=m;++i)
34 {
35 scanf("%lld%lld%lld",&u,&v,&w);
36 add(u,v,w);
37 add(v,u,w);
38 }
39 nod[1].dis=0;
40 q.push(nod[1]);
41 cnt=0;
42 prim();
43 printf("%lld",tot);
44 return 0;
45 }
46 void add(ll u,ll v,ll w)
47 {
48 e[++cnt].u=u;
49 e[cnt].v=v;
50 e[cnt].w=w;
51 e[cnt].nxt=h[u];
52 h[u]=cnt;
53 }
54 void prim()
55 {
56 while(!q.empty()&&cnt<n)
57 {
58 while(!q.empty()&&flag[q.top().t]) q.pop();
59 if(q.empty()) break;//上一个代码讲了
60 node g=q.top();
61 ll u=g.t;
62 flag[u]=true;
63 tot+=nod[u].dis;
64 q.pop();
65 for(rll i=h[u];i;i=e[i].nxt)
66 {
67 ll v=e[i].v,w=e[i].w;
68 if(w<nod[v].dis)
69 {
70 nod[v].dis=w;
71 q.push(nod[v]);
72 }
73 }
74 cnt++;
75 }
76 }

prim最小生成树算法(堆优化)的更多相关文章

  1. hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】

    题目1 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生 ...

  2. 图论——最小生成树prim+邻接表+堆优化

    今天学长对比了最小生成树最快速的求法不管是稠密图还是稀疏图,prim+邻接表+堆优化都能得到一个很不错的速度,所以参考学长的代码打出了下列代码,make_pair还不是很会,大体理解的意思是可以同时绑 ...

  3. Prim 最小生成树算法

    Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法.和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm). P ...

  4. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  5. Prim算法堆优化

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...

  6. P3366 【模板】最小生成树(堆优化prim)

    堆优化prim #include<cstdio> #include<cstring> #include<queue> using namespace std; st ...

  7. Dijkstra算法堆优化

    转自 https://blog.csdn.net/qq_41754350/article/details/83210517 再求单源最短路径时,算法有优劣之分,个人认为在时间方面 朴素dijkstra ...

  8. Dijkstra算法堆优化详解

    DIJ算法的堆优化 DIJ算法的时间复杂度是\(O(n^2)\)的,在一些题目中,这个复杂度显然不满足要求.所以我们需要继续探讨DIJ算法的优化方式. 堆优化的原理 堆优化,顾名思义,就是用堆进行优化 ...

  9. 最短路-朴素版Dijkstra算法&堆优化版的Dijkstra

    朴素版Dijkstra 目标 找到从一个点到其他点的最短距离 思路 ①初始化距离dist数组,将起点dist距离设为0,其他点的距离设为无穷(就是很大的值) ②for循环遍历n次,每层循环里找出不在S ...

随机推荐

  1. Solon 1.7.6 发布,更现代感的应用开发框架

    相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...

  2. 改善java程序

    1.用偶判断,不用奇判断.因为负数会出错. // 不使用 String str = i + "->" + (i%2 == 1? "奇数": "偶 ...

  3. C#/VB.NET 创建图片超链接

    超链接(Hyperlink)可以看做是一个"热点",它可以从当前Web页定义的位置跳转到其他位置,包括当前页的某个位置.Internet.本地硬盘或局域网上的其他文件,甚至跳转到声 ...

  4. JS 异步与 Promise

    JS 异步与 Promise 本文写于 2020 年 6 月 8 日 1. 同步与异步与回调函数 Promise 现在是前端面试必考题呀,但是先不急着看 Promise,我们首先来看看什么是异步. - ...

  5. 前后端分离,SpringBoot如何实现验证码操作

    验证码的功能是防止非法用户恶意去访问登录接口而设置的一个功能,今天我们就来看看在前后端分离的项目中,SpringBoot是如何提供服务的. SpringBoot版本 本文基于的Spring Boot的 ...

  6. OSError: no library called "cairo-2" was found

    环境 Windows 11 python 3.8.13 (anaconda->envs) PyCharm 场景 我使用了GitHub上的第三方组件进行GUI开发,https://github.c ...

  7. df-查看磁盘目录空间大小

    查看磁盘分区挂载情况. 语法 df [option] 选项 -T 显示文件系统类型. -h 带单位显示. 示例 [root@localhost ~]# df -Th Filesystem Type S ...

  8. 一文学完Linux常用命令

    一.Linux 终端命令格式 1.终端命令格式 完整版参考链接:Linux常用命令完整版 command [-options] [parameter] 说明: command : 命令名,相应功能的英 ...

  9. .Net分表分库动态化处理

    介绍 本期主角:ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业务代码入侵 背景 最近有个小伙伴来问我,分表下他有一批数据,这个 ...

  10. CSP-J游记

    祝大家 CSP-J/CSP-S 稳过第一轮 ~(- ∨ -)~ ~~ 建议扩大110%食用 ~~ 中秋快乐鸭(希望大家不会收到损友送的砖头月饼 : − ) :-) :−)) 咳咳,昨天是我们可爱初赛来 ...