https://www.luogu.org/problem/P3366
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz
写博客时发现好像没判图不连通情况,但是数据好像没有这种,可以过
用了小根堆优化,但好像更慢了??(强迫症患者表示必须小根堆优化下)
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #define ri register int #define u int #define NN 5005 #define MM 200005 namespace fast { inline u in() { u x(0); char s=getchar(); while(s<'0'||s>'9') { s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x; } } using fast::in; using std::queue; using std::pair; namespace all { u N,M,cnt,h[NN]; struct node { u to,next,va; } a[MM<<1]; inline void add(const u &x,const u &y,const u &z) { a[++cnt].next=h[x],a[cnt].to=y,a[cnt].va=z,h[x]=cnt; } u ans,num,vt[NN]; typedef pair<u,u> p; std::priority_queue<p, std::vector<p>, std::greater<p> > q; void prim(){ q.push(p(0,1)); while(num<=N-1){ u x(q.top().second),d(q.top().first); q.pop(); if(vt[x]) continue; ++num,ans+=d,vt[x]=1; for(ri i(h[x]);i;i=a[i].next){ u _y(a[i].to); q.push(p(a[i].va,_y)); } } } inline void solve(){ N=in(),M=in(); for(ri i(1);i<=M;++i){ u _a(in()),_b(in()),_c(in()); add(_a,_b,_c),add(_b,_a,_c); } prim(); printf("%d",ans); } } int main() { //freopen("x.txt","r",stdin); all::solve(); }