最小生成树
来源:互联网 发布:db2关闭数据库 编辑:程序博客网 时间:2024/06/05 16:33
最小生成树
——————————————————————————————————————
第二篇文章!!!!!
_____________________________________________________________________________________________________________________________________________________________
(1)prim算法(heap优化)
prim是一种最小生成树算法,它类似于dijkstra,基于一种贪心思想,每次选出可行的最短边加入生成树集合,这样计算出最后的结果。话不多说,因为其并不复杂,又已经有了dijkstra的铺垫(不知道可以看我的第一篇文章:单源最短路径),于是乎!我们直接上堆优化:
【代码】
<span style="font-size:18px;">program prim;type point=^node; node=record v,w:longint; next:point; end; ex=record w,i:longint; end;const maxn=10000;var p:point; x:ex; n,m,i,j,k,l,len,sum,ans:longint; a:array[1..maxn] of point; d:array[1..maxn] of longint; v:array[1..maxn] of boolean; heap:array[0..maxn*2+1] of ex; //类似dijkstra的说明procedure swap(var x,y:ex); //元素交换var t:ex;begin t:=x;x:=y;y:=t;end;procedure gettop(var x:ex); //取堆顶var k:longint; p:ex;begin x:=heap[1];heap[1]:=heap[len];heap[len].w:=maxlongint;len:=len-1; k:=1; while k<=len div 2 do begin if (heap[k].w<heap[2*k].w) and (heap[k].w<heap[2*k+1].w) then break; if heap[2*k].w<=heap[2*k+1].w then begin swap(heap[k],heap[2*k]); k:=k*2; end else begin swap(heap[k],heap[2*k+1]); k:=2*k+1; end; end;end;procedure put(x,l:longint); //插入元素var k:longint;begin len:=len+1;heap[len].w:=x;heap[len].i:=l; k:=len; while (k div 2>0) and (heap[k div 2].w>heap[k].w) do begin swap(heap[k div 2],heap[k]); k:=k div 2; end;end;procedure init; //读入begin readln(n,m); for i:=1 to maxn do a[i]:=nil; for l:=1 to m do begin readln(i,j,k); new(p);p^.v:=j;p^.w:=k;p^.next:=nil;p^.next:=a[i];a[i]:=p; new(p);p^.v:=i;p^.w:=k;p^.next:=nil;p^.next:=a[j];a[j]:=p; end;end;procedure prepare; //初始化begin fillchar(v,sizeof(v),false);v[1]:=true; fillchar(d,sizeof(d),$7f div 3); new(p);p:=a[1];while p<>nil do begin d[p^.v]:=p^.w;p:=p^.next; end;d[1]:=0; for i:=1 to maxn*2+1 do with heap[i] do begin w:=0;i:=0; end; heap[1].w:=0;heap[1].i:=1; //最小生成树不存在源点和终点,即所有点都要进去,所以我们为了方便,先将点1加入生成树集合,并入堆 len:=1;for i:=2 to n do put(d[i],i); ans:=0;sum:=1;end;procedure main; //prim算法begin repeat gettop(x); if v[x.i] then continue; sum:=sum+1;v[x.i]:=true;ans:=ans+d[x.i]; new(p);p:=a[x.i]; while p<>nil do begin if (not v[p^.v]) and (p^.w<d[p^.v]) then begin d[p^.v]:=p^.w; put(d[p^.v],p^.v); end; p:=p^.next; end; until sum=n;end;begin assign(input,'prim.in');reset(input); assign(output,'prim.out');rewrite(output); init; prepare; main; //调用一堆过程 write(ans); close(input);close(output);end.</span>
思想是:选择满足条件的最小边依次加入,有回路就掐,没有就进。
【代码】
以上就是最小生成树的算法,讲完了,再见。
<span style="font-size:18px;">program kruskal;type node=record u,v,w:longint; end;const maxn=10000;maxm=20000;var n,m,i,j,k,l,x,y,ans:longint; a:array[1..maxm] of node; //边集数组</span>
<span style="font-size:18px;"> f:array[1..maxn] of longint; //祖宗procedure qsort(l,r:longint); //对权值排序var i,j,x:longint; y:node;begin i:=l;j:=r;x:=a[(i+j) div 2].w; repeat while x>a[i].w do i:=i+1; while x<a[j].w do j:=j-1; if i<=j then begin y:=a[i];a[i]:=a[j];a[j]:=y; i:=i+1;j:=j-1; end; until i>j; if i<r then qsort(i,r); if l<j then qsort(l,j);end;function gen(x:longint):longint;begin if f[x]=0 then exit(x); gen:=gen(f[x]); f[x]:=gen;end;begin assign(input,'kruskal.in');reset(input); assign(output,'kruskal.out');rewrite(output); readln(n,m); for l:=1 to m do readln(a[l].u,a[l].v,a[l].w); //读入 qsort(1,m); fillchar(f,sizeof(f),0);j:=0; //初始化 for i:=1 to m do //kruskal begin x:=gen(a[i].u);y:=gen(a[i].v); if x<>y then begin f[x]:=y;j:=j+1; ans:=ans+a[i].w; end; if j=n-1 then break; //n-1条边已完成,退出 end; write(ans); //输出 close(input);close(output);end.</span>
以上就是最小生成树的算法,讲完了,再见。
1 0
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树Kruskal
- kruskal 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树问题
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- Text Justification
- 如何获得当前时间
- 企业关注技能知识点【Struts2框架】
- PostgreSQL:ERROR,0A000,"cached plan must not change result type"
- AsyncTask源码
- 最小生成树
- object-c 内存里面压缩与解压缩的函数
- C#数据录入表单按钮的Click事件
- ajax 分页实现方式
- 学习WebLogic11g集群搭建的一些心得
- 祝贺光环2014年6月28日PMP考试通过率90.28%
- 布隆过滤器demo
- MySQL的API接口
- 人体行为识别的几个入门文章和网址