Kruskal

声明

 

  洛谷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 算法 (学有余力的继续学习,学过的就算了)

 

posted @ 2018-10-05 21:07  》落雨~·~情缘《  阅读(181)  评论(0编辑  收藏  举报