洛谷P3366:https://www.luogu.org/problem/show?pid=3366
所需知识:快排、并查集。 (未学过的请先学习相关算法)
由于此模板较简单,我也不多解释,实在不会的看注释、看书、找资料~~
var u,v,w,f:array[0..1000001]of longint; n,m,i,j,s,ans:longint; procedure qsort(l,r:longint); //快排 var i,j,x,y:longint; begin i:=l; j:=r; x:=w[(l+r) div 2]; repeat while w[i]<x do inc(i); while w[j]>x do dec(j); if i<=j then begin y:=u[i]; u[i]:=u[j]; u[j]:=y; y:=v[i]; v[i]:=v[j]; v[j]:=y; y:=w[i]; w[i]:=w[j]; w[j]:=y; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if i<r then qsort(i,r); end; function find(x:longint):longint; //并查集路径压缩 begin if x=f[x] then exit(x) else begin f[x]:=find(f[x]); exit(f[x]); end; end; begin readln(n,m); for i:=1 to m do readln(u[i],v[i],w[i]); qsort(1,m); for i:=1 to n do //并查集初始化 f[i]:=i; ans:=w[1]; f[v[1]]:=u[1]; s:=1; for i:=2 to m do begin if s=n-1 then begin writeln(ans); halt; end; if find(u[i])<>find(v[i]) then //判断是否在同一集合 begin inc(ans,w[i]); f[find(v[i])]:=find(u[i]); //合并 inc(s); end; end; if s=n-1 then writeln(ans) else writeln('orz'); end.
放一个讲得较详细的博客:https://blog.csdn.net/qq_41754350/article/details/81460643
另外这里介绍最小生成树的另一种算法: Prim 算法 (学有余力的继续学习,学过的就算了)