典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法

来源:互联网 发布:js改变body的display 编辑:程序博客网 时间:2024/05/24 16:17
 

poj2449 Remmarguts' Date

分类: POJ解题报告 k短路径 A* 86人阅读 评论(0) 收藏 举报
date算法structc++c

典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法

k短路径的相关问题看这里,尽管已经是2007年的文章了,但作者真的写得非常详细和全面。

下面是一个简化的算法流程。

[cpp] view plaincopy
  1. /* 
  2.  * k短路径 Dijkstra+A*算法 
  3.  * 算法流程: 
  4.  * 1.将有向图的边反向后,Dijkstra求出任意节点到终点的最短路径 dis[i] 
  5.  * 2.优先队列  
  6.  *      struct 
  7.  *      { 
  8.  *          int v,l,d; 
  9.  *      }priority_queue[10000]; 
  10.  *  v:结点编号 
  11.  *  l:源点到v的距离 
  12.  *  d:源点经过v的到终点的某一条路径的长度 
  13.  *  优先队列以l为权值排序 
  14.  * 3.v = s,l = 0,d = 0; 入队 
  15.  *   每次从优先队列中取出并去除l最小的结点 
  16.  *   遍历结点v的所有后继,计算d,l并入队,不判断v的后继结点是否在队列中 
  17.  
  18.         for(i=head[k];i;i=edge[i].next) 
  19.         { 
  20.             q[++len].v = edge[i].v; 
  21.             q[len].d = dis[edge[i].v]+edge[i].d+q[l].l; 
  22.             q[len].l = q[l].l+edge[i].d; 
  23.             inq[len] = true; 
  24.             sum++; 
  25.         } 
  26.  * 4.第k次取出终点结点t,d即为第k短路径  
  27.  *   可能出现同一长度的不同路径,都会被分别找出 
  28.  * */  

[cpp] view plaincopy
  1. /* 
  2.  * poj2449 AC 
  3.  * k短路径 Dijkstra+A*算法 266ms 
  4.  * 第一次用STL,还不是很熟悉,以前都是手写二叉堆的。 
  5.  * Dijkstra开始写错了,导致TLE,一天不写手生。 
  6.  * 题目要注意,当终点和起点相同时,最短路径不是0,必须走一圈回来。 
  7.  * */  
  8. #include<stdio.h>  
  9. #include<memory.h>  
  10. #include<queue>  
  11. #include<fstream>  
  12. #include<vector>  
  13. using namespace std;  
  14.   
  15. #define INF 100000000  
  16. struct EDGE  
  17. {  
  18.     int v,t;  
  19.     long next;  
  20. }edge[100005],e[100005];  
  21. typedef struct   
  22. {  
  23.     long len,d;  
  24.     int v;  
  25. }NODE;  
  26. struct cmp  
  27. {  
  28.     bool operator()(const NODE &t1,const NODE &t2)  
  29.     {  
  30.         return t1.d>t2.d;  
  31.     }  
  32. };  
  33. long head[1005],h[1005];  
  34. long n,m,tot,tot1;  
  35. int a,b,c;  
  36. long dis[1005];  
  37.   
  38. void Dijkstra()  
  39. {  
  40.     bool vis[1005];  
  41.     NODE node,tmp;  
  42.     priority_queue<NODE,vector<NODE>,cmp> queue;  
  43.   
  44.     long i,j;  
  45.     for(i=1;i<=n;i++)  
  46.     {  
  47.         vis[i] = false;  
  48.         dis[i] = INF;  
  49.     }  
  50.     dis[b] = 0;  
  51.     node.d= 0,node.v = b;  
  52.     queue.push(node);  
  53.     for(i=1;i<=n;i++)  
  54.     {  
  55.         node = queue.top();  
  56.         queue.pop();  
  57.           
  58.         vis[node.v] = true;  
  59.         for(j=h[node.v];j;j=e[j].next)  
  60.             if(!vis[e[j].v] && dis[e[j].v]>dis[node.v]+e[j].t)  
  61.             {  
  62.                 dis[e[j].v] = dis[node.v]+e[j].t;  
  63.                 tmp.v = e[j].v;  
  64.                 tmp.d= dis[e[j].v];  
  65.                 queue.push(tmp);  
  66.             }  
  67.     }  
  68.     while(!queue.empty())  
  69.         queue.pop();  
  70.     return;  
  71. }  
  72.   
  73. long a_star()  
  74. {  
  75.     NODE node,tmp;  
  76.     long i,num = 0;  
  77.     priority_queue<NODE,vector<NODE>,cmp> queue;  
  78.     node.len = 0,node.d = 0,node.v = a;  
  79.     queue.push(node);  
  80.     while(!queue.empty())  
  81.     {  
  82.         node = queue.top();  
  83.         queue.pop();  
  84.         if(node.v==b)  
  85.         {  
  86.             num++;  
  87.             if(num==c) return node.d;  
  88.         }  
  89.         for(i=head[node.v];i;i=edge[i].next)  
  90.         {  
  91.             tmp.v = edge[i].v;  
  92.             tmp.d = node.len+edge[i].t+dis[edge[i].v];  
  93.             tmp.len = node.len+edge[i].t;  
  94.             queue.push(tmp);  
  95.         }  
  96.     }  
  97.     return -1;  
  98. }  
  99.   
  100. int main()  
  101. {  
  102. //  FILE* fin;  
  103. //  fin = fopen("d.in","r");  
  104.     scanf("%ld%ld",&n,&m);  
  105. //  fscanf(fin,"%ld%ld",&n,&m);  
  106.     int i,j,k,t;  
  107.     memset(head,0,sizeof(head));  
  108.     memset(h,0,sizeof(h));  
  109.     tot = tot1 = 0;  
  110.     for(i=1;i<=m;i++)  
  111.     {  
  112.         scanf("%d%d%d",&j,&k,&t);  
  113. //      fscanf(fin,"%d%d%d",&j,&k,&t);  
  114.         edge[++tot].v = k,edge[tot].t = t,edge[tot].next = head[j],head[j] = tot;  
  115.         e[++tot1].v = j,e[tot1].t = t,e[tot1].next = h[k],h[k] = tot1;  
  116.     }  
  117.     scanf("%d%d%d",&a,&b,&c);  
  118. //  fscanf(fin,"%d%d%d",&a,&b,&c);  
  119.     if(a==b) c++;  
  120.   
  121.     Dijkstra();  
  122.     long ans;  
  123.     ans = a_star();  
  124.     printf("%ld\n",ans);  
  125.     return 0;  
原创粉丝点击