0..0

来源:互联网 发布:matlab分水岭算法 编辑:程序博客网 时间:2024/04/28 08:01
const max=2139062144;   //取这个值是为了判节点取过没有var n,m,m1,s,t,ss:longint;    tail,sora,next,cost,d,b:array[0..100000]of longint;function min(x,y:longint):longint;//不可用maths库 因为线段树中存的是节点序号begin if d[b[x]]<d[b[y]] then exit(b[x]) else exit(b[y])end;procedure change(x,y:longint);    //修改线段树begin d[x]:=y;inc(x,m1);x:=x>>1; while x<>0 do begin b[x]:=min(x<<1,x<<1+1);x:=x>>1 end;//还可以优化速度,不过为了拼行数 没加优化end;procedure origin;begin s:=1;t:=n;ss:=t;fillchar(d,sizeof(d),127); for m1:=s to t do tail[m1]:=m1; m1:=1;while m1<=n do m1:=m1<<1;dec(m1);   //计算叶子 for t:=1 to t do b[t+m1]:=t                      //线段树初始化end;procedure link(x,y,z:longint);   //邻接表begin inc(ss);next[tail[x]]:=ss;sora[ss]:=y;cost[ss]:=z;tail[x]:=ss; inc(ss);next[tail[y]]:=ss;sora[ss]:=x;cost[ss]:=z;tail[y]:=ssend;procedure init;var i,x,y,z,ne,cos:longint;begin readln(n,m);origin; for i:=1 to m do begin readln(x,y,z);link(x,y,z) end;  // 输入连边 x:=s;d[s]:=0; while x<>t do begin  i:=x;cos:=d[x];change(x,maxlongint);  //维护      while next[i]<>0 do begin   i:=next[i];ne:=sora[i];   if (d[ne]<max)and(cos+cost[i]<d[ne]) then change(ne,cos+cost[i])   //修改  end;  x:=b[1]                        //取距离最近点 end; writeln(d[t])end;begin initend.//做的是无向图,还没测过速,不过只有43行(+heap有70+行)理论复杂度是 修改o(log n);取最小节点 o(1) 但维护又要o(log n)。//实际运行上常数可能会比+heap大。加了优化可能会更快。


0 0