您的位置:首页 > 其它

【模板】最小生成树Prim 4heap

2017-09-15 07:52 357 查看
基本介绍

模板题目

代码实现

基本介绍

终于来填Prim的坑了 代码实现和最短路的Dijkstra差不多 也用的堆优化

大体意思就是说 现在图中选取一个蓝点染成白色 然后遍历与这个点相连的所有边 选取最短的边然后将另一个端点染成白色 再遍历这个点 从所有白点中找最短的 一直这样下去 stl小根堆比较好 便于每次找短的

模板题目

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例:

4 5

1 2 2

1 3 2

1 4 3

2 3 4

3 4 3

输出样例:

7

代码实现

#include<iostream>
#include<cstdio>
#include<cctype>
#include<queue>

using namespace std;
#define in = read()
typedef long long ll;
const ll size = 1000000 + 10000;

struct point{   ll next,to,dis;}edge[size];
priority_queue<pair<ll , ll> , vector<pair<ll , ll> > , greater<pair<ll , ll> > > q;

ll n,m;
ll site,ans,total,u;
ll head[size];
bool exist[size];

inline ll read(){
ll num = 0 , f = 1;   char ch = getchar();

while(!isdigit(ch)){
if(ch == '-')   f = -1;
ch = getchar();
}

while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}

return num*f;
}

inline void add(ll x,ll y,ll z){
edge[++site].next = head[x];
edge[site].to = y;
edge[site].dis = z;
head[x] = site;
}

int main(){
n in;   m in;
for(int i=1;i<=m;i++){
ll x,y,z;   x in;   y in;   z in;
add(x,y,z);   add(y,x,z);
}

pair<ll , ll> x;
q.push(make_pair(0,1));
while(!q.empty() && total != n - 1){
x = q.top();    q.pop();    u = x.second;
if(exist[u])    continue;
exist[u] = true;
ans += x.first;
total --;
for(int i=head[u];i;i=edge[i].next)
if(!exist[edge[i].to])
q.push(make_pair(edge[i].dis,edge[i].to));
}

printf("%d",ans);
}

//COYG
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: