一直以来只会Kruskal

prim和dijkstra很像

只不过prim维护的是最短的边,而dijkstra维护的是最短的从起点到一个点的路径

同时prim要注意当前拓展的边是没有拓展过的

可以用堆优化

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; const int MAXN = + ;
const int MAXM = 2e5 + ; struct Edge{ int to, w, next; };
Edge e[MAXM << ];
int head[MAXN], d[MAXN], vis[MAXN], n, m, tot; void AddEdge(int from, int to, int w)
{
e[tot] = Edge{to, w, head[from]};
head[from] = tot++;
} void read(int& x)
{
int f = ; x = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -; ch = getchar(); }
while(isdigit(ch)) { x = x * + ch - ''; ch = getchar(); }
x *= f;
} void prim()
{
vis[] = ;
_for(i, , n) d[i] = i == ? : 1e9;
for(int i = head[]; ~i; i = e[i].next)
{
int v = e[i].to;
d[v] = min(d[v], e[i].w);
} int ans = ;
REP(k, , n)
{
int mint = 1e9, id;
_for(i, , n)
if(!vis[i] && d[i] < mint)
{
mint = d[i];
id = i;
} ans += mint;
vis[id] = ; for(int i = head[id]; ~i; i = e[i].next)
{
int v = e[i].to;
if(vis[v]) continue;
d[v] = min(d[v], e[i].w);
}
}
printf("%d\n", ans);
} int main()
{
memset(head, -, sizeof(head)); tot = ;
read(n); read(m);
_for(i, , m)
{
int u, v, w;
read(u); read(v); read(w);
AddEdge(u, v, w);
AddEdge(v, u, w);
}
prim();
return ;
}

堆优化版本

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; const int MAXN = + ;
const int MAXM = 2e5 + ; struct Edge{ int to, w, next; };
Edge e[MAXM << ];
int head[MAXN], d[MAXN], vis[MAXN], n, m, tot; void AddEdge(int from, int to, int w)
{
e[tot] = Edge{to, w, head[from]};
head[from] = tot++;
} void read(int& x)
{
int f = ; x = ; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -; ch = getchar(); }
while(isdigit(ch)) { x = x * + ch - ''; ch = getchar(); }
x *= f;
} struct node
{
int id, w;
bool operator < (const node& rhs) const
{
return w > rhs.w;
}
};
priority_queue<node> q; void prim()
{
vis[] = ;
_for(i, , n) d[i] = i == ? : 1e9;
for(int i = head[]; ~i; i = e[i].next)
{
int v = e[i].to;
d[v] = min(d[v], e[i].w);
}
_for(i, , n) q.push(node{i, d[i]}); int ans = ;
REP(k, , n)
{
int mint, id;
while()
{
node x = q.top(); q.pop();
if(vis[x.id]) continue;
id = x.id, mint = x.w;
break;
} ans += mint;
vis[id] = ; for(int i = head[id]; ~i; i = e[i].next)
{
int v = e[i].to;
if(vis[v]) continue;
if(d[v] > e[i].w)
{
d[v] = e[i].w;
q.push(node{v, d[v]});
}
}
}
printf("%d\n", ans);
} int main()
{
memset(head, -, sizeof(head)); tot = ;
read(n); read(m);
_for(i, , m)
{
int u, v, w;
read(u); read(v); read(w);
AddEdge(u, v, w);
AddEdge(v, u, w);
}
prim();
return ;
}

prim求最小生成树的更多相关文章

  1. Codeforces 632F - Magic Matrix(暴力 bitset or Prim 求最小生成树+最小瓶颈路)

    题面传送门 开始挖老祖宗(ycx)留下来的东西.jpg 本来想水一道紫题作为 AC 的第 500 道紫题的,结果发现点开了道神题. 首先先讲一个我想出来的暴力做法.条件一和条件二直接扫一遍判断掉.先将 ...

  2. POJ 1258 Agri-Net(Prim求最小生成树)

    Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64912   Accepted: 26854 Descri ...

  3. HDU 3371 kruscal/prim求最小生成树 Connect the Cities 大坑大坑

    这个时间短 700多s #include<stdio.h> #include<string.h> #include<iostream> #include<al ...

  4. 新疆大学(新大)OJ xju 1009: 一带一路 prim求最短路径+O(n)素数筛选

    1009: 一带一路 时间限制: 1 Sec  内存限制: 128 MB 题目描述 一带一路是去去年习大大提出来的建设“新丝绸之路经济带”和“21世纪海上丝绸之路”的战略构想.其中就包括我们新疆乌鲁木 ...

  5. HDU-1233 还是畅通工程 (prim 算法求最小生成树)

    prim 算法求最小生成树 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  6. Kruskal和Prim算法求最小生成树

    Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...

  7. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  8. 求最小生成树(暴力法,prim,prim的堆优化,kruskal)

    求最小生成树(暴力法,prim,prim的堆优化,kruskal) 5 71 2 22 5 21 3 41 4 73 4 12 3 13 5 6 我们采用的是dfs的回溯暴力,所以对于如下图,只能搜索 ...

  9. 858. Prim算法求最小生成树(模板)

    给定一个n个点m条边的无向图,图中可能存在重边和自环,边权可能为负数. 求最小生成树的树边权重之和,如果最小生成树不存在则输出impossible. 给定一张边带权的无向图G=(V, E),其中V表示 ...

随机推荐

  1. oracle regexp_like介绍和例子

    oracle regexp_like介绍和例子 学习了:http://www.cnblogs.com/einyboy/archive/2012/08/01/2617606.html ORACLE中的支 ...

  2. 在windows下怎样更新vundle?

    本文出自Svitter的blog 更新Vundle的时候.不管是输出BundleInstall.还是PluginInstall! 都会调用系统的git,所以必须安装git才干达到目的更新插件. git ...

  3. NSAttributedString宽高计算小技巧

    通常对于CoreText之类自己实现绘制的控件来说,计算富文本的宽高事实上须要依赖CTFramesetterSuggestFrameSizeWithConstraints这种方法. 但有些时候.我们可 ...

  4. C#实现动态调用Windows DLL

    调用方法: object obj = WinDllInvoke("Kernel32.dll", "Beep", , }, typeof(void)); 函数代码 ...

  5. 优雅的App全然退出方案(没有不论什么内存泄漏隐患)

    在Android开发过程中,特别是界面比較多的情况下,用寻常的退出方式往往是不能全然退出这个应用,网络上也好多各种退出方案.当中一种应该是被广大开发人员採纳使用,也很的清晰方便.就是在Applicat ...

  6. luogu1347 排序

    题目大意 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列.给你一系列形如A<B的关系,并要求你判断是否能够根据这些关系确定这个数列的顺序(能,矛盾,不确定).确定n个元素的顺序后 ...

  7. python 读取二进制文件 转为16进制输出

    示例: #!/usr/bin/env python #encoding: utf-8 import binascii fh = open(r'C:\Temp\img\2012517165556.png ...

  8. Python 字典(dict)操作(update)

    1. get 注意以下两种形式的细微差别,差别在返回值的类型上: d.get(value, '') d.get(value, ['']) >> d = {} >> d.get( ...

  9. OC数组和字典中存入niu值

    在NSArray和NSDictionary中nil有特殊的含义.但是某些时候,我们必须要放入nil怎么办? 要想放入nil就必须用到一个类NSNull,这个类只有一个类方法,就是null.[NSNul ...

  10. BZOJ 4756 线段树合并(线段树)

    思路: 1.最裸的线段树合并 2. 我们可以观察到子树求一个东西 那我们直接DFS序好了 入队的时候统计一下有多少比他大的 出的时候统计一下 减一下 搞定~ 线段树合并代码: //By SiriusR ...