基本介绍
模板题目
代码实现
基本介绍
终于来填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