zoukankan      html  css  js  c++  java
  • poj3255,poj2449

    这里介绍怎么求k短路

    A*搜索 估价函数f[i]=g[i]+h[i];

    在这里g[i]表示到达点i当前路径长,h[i]表示点i到达终点的最短距离

    在搜索中,每次都取队列估价函数值最小的点,然后把它所能到达的点更新进入队列

    显然这需要一个优先队列来维护(heap)

    当终点第k次出队时,当前路径长度就是k短路

      1 const max=1000000000;
      2 type link=^node;
      3      node=record
      4        po,len:longint;
      5        next:link;
      6      end;
      7      point=record
      8        data,num:longint;
      9      end;
     10 var w,ow:array[0..1010] of link;
     11     v:array[0..1010] of boolean;
     12     d:array[0..1010] of longint;
     13     heap:array[0..1004010] of point;   //堆维护估价函数值
     14     st,en,i,n,m,j,t,k,x,y,z,s:longint;
     15     p:link;
     16 
     17 procedure sift(x:longint);    //堆的下沉
     18   var i,j:longint;
     19   begin
     20     i:=x;
     21     j:=i*2;
     22     while j<=t do
     23     begin
     24       if (j+1<=t) and (heap[j].data>heap[j+1].data) then inc(j);
     25       if heap[i].data>heap[j].data then
     26       begin
     27         swap(heap[i],heap[j]);
     28         i:=j;
     29         j:=i*2;
     30       end
     31       else exit;
     32     end;
     33   end;
     34 
     35 procedure up(x:longint);   //堆的上浮
     36   var i,j:longint;
     37   begin
     38     i:=x;
     39     j:=i div 2;
     40     while j>0 do
     41     begin
     42       if heap[i].data<heap[j].data then
     43       begin
     44         swap(heap[i],heap[j]);
     45         i:=j;
     46         j:=i div 2;
     47       end
     48       else exit;
     49     end;
     50   end;
     51 
     52 procedure add(x,y:longint;var q:link);
     53   var p:link;
     54   begin
     55     new(p);
     56     p^.po:=y;
     57     p^.len:=z;
     58     p^.next:=q;
     59     q:=p;
     60   end;
     61 
     62 procedure dij;     //求点到终点的距离
     63   var p:link;
     64   begin
     65     fillchar(v,sizeof(v),false);
     66     v[en]:=true;
     67     for i:=1 to n do
     68       d[i]:=max;
     69     d[en]:=0;
     70     p:=ow[en];
     71     while p<>nil do
     72     begin
     73       d[p^.po]:=min(d[p^.po],p^.len);   //用邻接表重要的细节
     74       p:=p^.next;
     75     end;
     76     for i:=1 to n-2 do
     77     begin
     78       x:=max;
     79       y:=0;
     80       for j:=1 to n do
     81         if not v[j] and (d[j]<x) then
     82         begin
     83           x:=d[j];
     84           y:=j;
     85         end;
     86       if x=max then exit;
     87       v[y]:=true;
     88       p:=ow[y];
     89       while p<>nil do
     90       begin
     91         d[p^.po]:=min(d[p^.po],p^.len+x);
     92         p:=p^.next;
     93       end;
     94     end;
     95   end;
     96 
     97 function astar(st,ed:longint):longint;
     98   var p:link;
     99   begin
    100     heap[1].data:=d[st];
    101     heap[1].num:=st;
    102     t:=1;
    103     s:=0;
    104     astar:=-1;
    105     while t<>0 do
    106     begin
    107       x:=heap[1].num;    //退队
    108       y:=heap[1].data-d[x];  
    109       swap(heap[1],heap[t]);
    110       dec(t);
    111       sift(1);
    112       if x=en then
    113       begin
    114         s:=s+1;
    115         if s=k then exit(y);
    116       end;
    117       p:=w[x];
    118       while p<>nil do      //更新所有能到达的点入队
    119       begin
    120         inc(t);
    121         heap[t].num:=p^.po;
    122         heap[t].data:=y+p^.len+d[p^.po];
    123         up(t);
    124         p:=p^.next;
    125       end;
    126     end;
    127   end;
    128 
    129 begin
    130   readln(n,m);
    131   for i:=1 to m do
    132   begin
    133     readln(x,y,z);
    134     add(x,y,w[x]);
    135     add(y,x,ow[y]);    //注意有向需反向建边,快速求点到终点的距离
    136   end;
    137   readln(st,en,k);
    138   if st=en then inc(k);  //注意终点与起点重合时,路径为0的不算
    139   dij;
    140    writeln(astar(st,en));
    141 end.
    View Code

    而对于poj3255,求无向图的次短路也可以用A*,在n<=5000时还是可以过的,注意那时候就不需要反向建边了

    k短路算法还是很好理解的

  • 相关阅读:
    复利完结观看评价
    汉堡计划
    0406 复利计算完结篇
    构建之法 第四章 读后感
    复利计算单元测试
    实验一 cmd命令的编写
    构建之法 前三章读后感
    复利计算完成总结
    复利计算软件v3
    实验 0 了解和熟悉操作系统
  • 原文地址:https://www.cnblogs.com/phile/p/4473282.html
Copyright © 2011-2022 走看看