题目链接:http://hihocoder.com/problemset/problem/1109 , 最小生成树 + 堆优化(优先队列)。

  可以用优先队列,也可以自己手动模拟堆,为了练手,我两种都试了下,优先队列还是要方便一点,不过堆要快一点。

  没有无缘无故的爱,也没有无缘无故减少的时间复杂度。所以,好好学算法。

 


堆优化的代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = + ;
struct Edge { //邻接表表示图
int v , w;
bool operator < (const Edge &tmp) const {
return w < tmp.w;
}
} a[maxn];
vector <Edge> e[maxn];
int vis[maxn] , dist[maxn]; void PushUp(int rt , int r)
{ //自下向上更新以rt为根,r为右边界的堆
int i = r >> ;
while(i >= rt) {
if(a[r] < a[i]) {
swap(a[r] , a[i]);
r = i;
i >>= ;
} else {
break;
}
}
}
void PushDown(int rt , int r)
{ //自上向下更新以rt为根,r为右边界的堆
int i = rt << ;
while(i <= r) {
if(a[i].w > a[i + ].w)
i++;
if(a[i] < a[rt]) {
swap(a[i] , a[rt]);
rt = i;
i <<= ;
} else {
break;
}
}
}
int Prim(int s , int n)
{
int tot , ans; //tot表示堆中元素的个数
tot = ans = ;
memset(vis , , sizeof(vis));
for(int i = ; i <= n ; i++)
dist[i] = INF;
a[++tot].v = s;
a[tot].w = ;
while(tot >= ) {
Edge u = a[];
swap(a[] , a[tot]);
a[tot--].w = INF;
PushDown( , tot);  
if(vis[u.v])
continue;
ans += u.w;
vis[u.v] = ;
for(int i = ; i < e[u.v].size() ; i++) {
int j = e[u.v][i].v;
if(dist[j] > e[u.v][i].w) {
dist[j] = e[u.v][i].w;
if(!vis[j]) {
a[++tot] = e[u.v][i];
PushUp( , tot);
}
}
}
}
return ans;
}
int main()
{
int n , m , u , v , w;
scanf("%d %d" , &n , &m);
while(m--) {
scanf("%d %d %d" , &u , &v , &w);
Edge tmp = {v , w};
e[u].push_back(tmp);
tmp.v = u;
e[v].push_back(tmp);
}
printf("%d\n" , Prim( , n));
return ;
}

优先队列优化(注意重载运算符地方的细节):

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = + ;
struct Edge {
int v , w;
bool operator < (const Edge &tmp) const {
return w > tmp.w;
}
} a[maxn];
vector <Edge> e[maxn];
int vis[maxn] , dist[maxn]; int Prim(Edge s , int n)
{
priority_queue <Edge> que;
int ans = ;
for(int i = ; i <= n ; i++) {
dist[i] = INF;
vis[i] = ;
}
que.push(s);
while(!que.empty()) {
Edge u = que.top();
que.pop();
if(vis[u.v])
continue;
vis[u.v] = ;
ans += u.w;
for(int i = ; i < e[u.v].size() ; i++) {
int j = e[u.v][i].v;
if(dist[j] > e[u.v][i].w && !vis[j]) {
dist[j] = e[u.v][i].w;
que.push(e[u.v][i]);
}
}
}
return ans;
}
int main()
{
int n , m , u , v , w;
scanf("%d %d" , &n , &m);
while(m--) {
scanf("%d %d %d" , &u , &v , &w);
Edge tmp = {v , w};
e[u].push_back(tmp);
tmp.v = u;
e[v].push_back(tmp);
}
Edge tmp = { , };
printf("%d\n" , Prim(tmp , n));
return ;
}

hihocoder 1109 堆优化的Prim算法的更多相关文章

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

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

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

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

  3. 图论之堆优化的Prim

    本题模板,最小生成树,洛谷P3366 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边 ...

  4. Hihocoder 之 #1097 : 最小生成树一·Prim算法 (用vector二维 模拟邻接表,进行prim()生成树算法, *【模板】)

    #1097 : 最小生成树一·Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可 ...

  5. 堆优化的dijkstra算法

    #include<bits/stdc++.h> using namespace std; #define ll long long #define P pair<int,int> ...

  6. Prim算法堆优化

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

  7. 图论——最小生成树:Prim算法及优化、Kruskal算法,及时间复杂度比较

    最小生成树: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.简单来说就是有且仅有n个点n-1条边的连通图. 而最小生成树就是最小权 ...

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

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

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

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

随机推荐

  1. CEPH安装教程(中)

    NTP服务配置 NTP客户端配置 # vim /etc/ntp.conf server 92.0.0.250 ### 手动同步下时间 # ntpdate -u 92.0.0.250 ### 启动服务 ...

  2. elasticsearch 聚合查询

    1. 按照 tags 字段 进行分组 GET /ecommerce/product/_search{ "size": 0,  "aggs": {    &quo ...

  3. JavaWeb:JSP技术基础

    JavaWeb:JSP技术 快速开始 介绍 JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%> ...

  4. Java:基本语法

    Java语言是由类和对象组成的,其对象和类又是由变量和方法组成,而方法,又包含了语句和表达式. 1. 变量 Java语言提供了两种变量:成员变量和局部变量 成员变量:是在方法体外的类中声明和定义的,可 ...

  5. P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

    题意:n个点,求凸包周长.(纯板子QAQ) 定义 凸包:用最小的凸多边形将n个点围在里面的图形为凸包 前置 向量:点积:(a,b) (c,d)=(a*c,b*d) =|(a,b)|*|(c,d)|*c ...

  6. 洛谷 P1551 亲戚(并查集模板)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P1551 思路: 很显然地我们会发现,这是一道并查集的模板题,并且是考察了并查集中的”并“和”查“的操 ...

  7. 原生JS轮播-各种效果的极简实现

    寒假持续摸鱼中~此为老早以前博客的重写,当时还是分开写的,这里汇总重写,正好复习一遍~ 春招我来了! 所有有意思的,一股脑先扔进收藏,然后再也不看哈哈,真是糟糕. 今日事,今日毕,说起来容易. 当时竟 ...

  8. 默认约束 default

    default :初始值设置,插入记录时,如果没有明确为字段赋值,则自动赋予默认值.  例子:create table tb6(   id int primary key auto_increment ...

  9. Docker从入门到实战(四)

    Docker基础 一:Docker基本操作 一般情况安装Docker之后系统会自动创建一个Docker的用户组,如果没有创建可以手动创建groupadd docker把当前非root用户加入group ...

  10. Murano Weekly Meeting 2015.07.21

    会议时间: 2015.07.21 主持人: Kirill Zaitsev, core from Mirantis 会议摘要:  1.murano client和murano dashboard升级到y ...