本题模板,最小生成树,洛谷P3366

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入输出格式

输入格式:

第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

输出格式:

输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

输入输出样例

输入样例#1:

4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例#1:

7

说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=20

对于40%的数据:N<=50,M<=2500

对于70%的数据:N<=500,M<=10000

对于100%的数据:N<=5000,M<=200000

下面介绍堆优化后的Prim

首先清楚prim的过程:

给出一个适用于这类问题的推论:给定一张无向图G=(V,E)。n=V的大小,m=E的大小。从E中选出k<n-1条边构成G的一个生成森林。若再从剩余的m-k条边选n-1-k条添加到生成森林中,使其成为G的生成树,并且选出的边的权值之和最小,则该生成树一定包含这m-k条边中连接两个森林的不连通节点的最小边

无论是Prim还是Kruskal都是基于这个推论,但Prim略微有一些改动。

Prim算法总是维护最小生成树的一部分。最初,Prim算法仅确定1号节点属于最小生成树。在任意的时刻,设已经确定属于最小生成树的节点集合为T,剩余节点集合为S。Prim算法找到min(x属于S,y属于T){z},即两个端点分别属于集合S,T的权值最小的边,然后把点x从集合S中删除,加入到集合T中去,并把Z累计到答案(最后答案就是最小生成树的边权值和)。

具体来说,可以维护数组d:对于x属于S,则把d[x]表示节点x与集合T中的节点之间权值最小的边的权值。若x属于T,则d[x]就等于x被加入T选出的最小边的权值

用一个数组标记节点是否属于T。每次从未标记的节点中选出d值最小的,把它标记(加入T),同时
扫描所有出边,更新另一个端点的d值。最后得出答案

可用二叉堆将上述的d数组优化,但其实都不如Kruskal方便。因此Prim主要用于稠密图,尤其是完全图的最下生成树的求解

那么所谓的二叉堆优化实际上就是对于每一次拓展的边加入到一个小根堆中,下面笔者的代码实现用的是priority_queue(我懒)

具体实现看代码

注意不仅要判断堆是否为空还要统计已经维护的点的个数,确保还是小于等于n的

#include<bits/stdc++.h>
#define ll long long
using namespace std; const int maxn=2e5+;
const int mxn=5e3+;
struct node
{
int t;int d;
bool operator < (const node &a) const
{
return d>a.d;
}
};
int n,m;
int vis[mxn];
vector <node> e[mxn];
priority_queue <node> q;
inline int read()
{
char ch=getchar();
int s=,f=;
while (!(ch>=''&&ch<='')) {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
ll prim()
{
ll ans=;
int cnt=;
q.push((node){,});
while (!q.empty()&&cnt<=n)
{
node k=q.top();q.pop();
if (vis[k.t]) continue;
vis[k.t]=;
ans+=k.d;
cnt++;
for (int i=;i<e[k.t].size();i++)
if (!vis[e[k.t][i].t]){
q.push((node){e[k.t][i].t,e[k.t][i].d});
}
}
return ans;
}
int main()
{
n=read();m=read();
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
e[x].push_back((node){y,z});e[y].push_back((node){x,z});
}
printf("%lld",prim());
return ;
}

图论之堆优化的Prim的更多相关文章

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

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

  2. hihocoder 1109 堆优化的Prim算法

    题目链接:http://hihocoder.com/problemset/problem/1109 , 最小生成树 + 堆优化(优先队列). 可以用优先队列,也可以自己手动模拟堆,为了练手,我两种都试 ...

  3. hihoCoder#1109 最小生成树三·堆优化的Prim算法

    原题地址 坑了我好久...提交总是WA,找了个AC代码,然后做同步随机数据diff测试,结果发现数据量小的时候,测试几十万组随机数据都没问题,但是数据量大了以后就会不同,思前想后就是不知道算法写得有什 ...

  4. Prim算法堆优化

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

  5. POJ-1287.Network(Kruskal + Prim + Prim堆优化)

    Networking Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19674   Accepted: 10061 Desc ...

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

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

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

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

  8. dijkstra(最短路)和Prim(最小生成树)下的堆优化

    dijkstra(最短路)和Prim(最小生成树)下的堆优化 最小堆: down(i)[向下调整]:从第k层的点i开始向下操作,第k层的点与第k+1层的点(如果有)进行值大小的判断,如果父节点的值大于 ...

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

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

随机推荐

  1. 每天学点Python之comprehensions

    每天学点Python之comprehensions 推导式能够简化对数据的处理,让代码简洁的同一时候还具有非常高的可读性.这在Python中非经常见. 列表推导式 通过列表推导式能够对列表中的全部元素 ...

  2. 同一个TextView设置不同的颜色和大小

    //strategy1是一个TextView SpannableStringBuilder builder1 = new SpannableStringBuilder(strategy1.getTex ...

  3. HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException

    HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException type ...

  4. nyoj--2--括号配对问题(栈函数)

    括号配对问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 现在,有一行括号序列,请你检查这行括号是否配对. 输入 第一行输入一个数N(0<N<=100), ...

  5. sicily 1146 采药 (动规)

    打代码不走心会掉坑里的.. 下边是代码: //1146.采药 //t表示总时间 //m表示草药数 //w表示采药时间 //v表示草药价值 #include <iostream> using ...

  6. Dos.ORM使用教程

    Dos.C#.Net使用 Dos.ORM(原Hxj.Data)于2009年发布,并发布实体生成工具.在开发过程参考了多个ORM框架,特别是NBear,MySoft.EF.Dapper等.吸取了他们的一 ...

  7. HTML的常用标签属性及使用时需注意的一些细节

    前言 本篇随笔的主要是复习一下常用的一些HTML(Hyper Text Markup Language)标签及其属性,并总结一些使用过程中需要注意的一些细节,本篇提及的常用标签主要有: iframe标 ...

  8. Sublime使用随记

    1.安装 Package Control Ctrl+` 打开命令行,执行如下代码: 适用于 Sublime Text 3: import urllib.request,os;pf='Package C ...

  9. Caffe学习--Blob分析

    Caffe_blob 1.基本数据结构 Blob为模板类,可以理解为四维数组,n * c * h * w的结构,Layer内为blob输入data和diff,Layer间的blob为学习的参数.内部封 ...

  10. 洛谷3627 [APIO2009]抢掠计划

    题目描述 输入格式: 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点 ...