最小生成树(并查集)

来源:互联网 发布:淘宝用绒里图片 编辑:程序博客网 时间:2024/04/28 02:35

题意:

找一课最小生成树

思路:

基本思想:每次选不属于同一连通分量(保证无圈)且边权值最小的2个顶点,将边加入MST,并将所在的2个连通分量合并,直到只剩一个连通分量
算法实现:
将边按非降序排列(Quicksort,O(E㏒E))
While 合并次数少于|V|-1
取一条边(u,v)(因为已经排序,所以必为最小)
If u,v不属于同一连通分量 then
合并u,v所在的连通分量
输出边(u,v)
合并次数增1;tot=tot+W(u,v)
算法结束:tot为MST的总权值
直接复制了一波课件,因为这题太简单、

type  arr=record  x,y,w:longint; end;const maxn=1000;var a:array [0..maxn*maxn] of arr; f:array [0..maxn*maxn] of longint; i,j,n,m,p,ans:longint;procedure qsort(l,r:longint);var i,j,mid:longint;begin i:=l; j:=r; mid:=a[(l+r) div 2].w; while i<j do begin  while a[i].w<mid do inc(i);  while a[j].w>mid do dec(j);  if i<=j then  begin   a[0]:=a[i];   a[i]:=a[j];   a[j]:=a[0];   inc(i); dec(j);  end; end; if i<r then qsort(i,r); if l<j then qsort(l,j);end;function father(x:longint):longint;var i,j:longint;begin if x<>f[x] then father:=father(f[x])            else father:=x; f[x]:=father;end;begin readln(n); for i:=1 to n do begin  for j:=1 to n do  if i<j then  begin   inc(p);   read(a[p].w);   a[p].x:=i;   a[p].y:=j;  end;  readln; end; qsort(1,p); for i:=1 to p do  f[i]:=i; for i:=1 to p do  if f[father(a[i].x)]<>f[father(a[i].y)] then  begin   f[father(a[i].x)]:=f[father(a[i].y)];   ans:=ans+a[i].w;  end; writeln(ans);end.
0 0
原创粉丝点击