POJ 2449 Remmarguts' Date K最短路问题(单源点最短路径+A*算法)
来源:互联网 发布:微博桌面2015网络异常 编辑:程序博客网 时间:2024/05/17 02:47
算法解释感谢Jarily http://blog.csdn.net/jarily/article/details/8871968
/* *算法引入: *在单源点最短路径问题中,实际运用时还需知道最短路径外,次短路或者第三短路; *即要知道多条最短路,并排出其长度增加的顺序,即为K最短路问题; * *算法思想: *单源点最短路径+高级搜索A*; *A*算法结合了启发式方法和形式化方法; *启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大降低; *形式化方法不利用图给出的信息,而仅通过数学的形式分析; * *算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向; *当这条路径失败时,它会尝试其他路径; *对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个; * *对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度; *f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远; * *为了加速计算,h(p)需要在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源点最短路径就能得到每个点的h(p)了; * *算法步骤: *(1),将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离; *(2),新建一个优先队列,将源点s加入到队列中; *(3),从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数; *如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束; *否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列; * *算法测试: *PKU2449(Remmarguts' Date) * *题目大意: *求从s到t的第k短路的长度; */#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;#define N 1010#define M 100010#define INF 1e9typedef int type;type dis[N];int out[N];bool visit[N];struct Node{ int pos; type g,f; // g(i) 为从start到i目前已走的距离 , f(i)=g(i)+dis(i) friend bool operator<(Node a,Node b) { return a.f>b.f; }};struct{ int to,next; type c;}edge[M<<1];int ip;int head1[N],head2[N];void addedge1(int u,int v,type c){ edge[ip].to=v; edge[ip].c=c; edge[ip].next=head1[u]; head1[u]=ip++;}void addedge2(int u,int v,type c){ edge[ip].to=v; edge[ip].c=c; edge[ip].next=head2[u]; head2[u]=ip++;}bool spfa(int start,int end,int n) //以end为起点求i到end的最短路{ queue<int>q; memset(out,0,sizeof(out)); memset(visit,0,sizeof(visit)); for(int i=0;i<=n;i++) dis[i]=INF; q.push(start); visit[start]=1; dis[start]=0; int top; while(!q.empty()) { top=q.front(); q.pop(); visit[top]=0; out[top]++; if(out[top]>n) return 0; for(int p=head2[top];p!=-1;p=edge[p].next) { if(dis[ edge[p].to ] > dis[top] + edge[p].c ) { dis[edge[p].to]=dis[top]+edge[p].c; if(!visit[edge[p].to]) { visit[edge[p].to]=1; q.push(edge[p].to); } } } } if(dis[end]==INF) return 0; return 1;}int K_load(int start,int end,int k){ Node top,temp; priority_queue<Node>q; int time=0; top.pos=start; top.g=0; top.f=dis[start]; q.push(top); while(!q.empty()) { top=q.top(); q.pop(); if(top.pos==end) time++; if(time==k) return top.f; for(int p=head1[top.pos];p!=-1;p=edge[p].next) { temp.pos=edge[p].to; temp.g=top.g+edge[p].c; temp.f=temp.g+dis[edge[p].to]; q.push(temp); } } return -1;}int solve(int start,int end,int k,int n){ if(!spfa(end,start,n)) return -1; return K_load(start,end,k);}int main(){ int n,m; int x,y; int start,end,k; type c; while(cin>>n>>m) { ip=0; memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); while(m--) { scanf("%d%d%d",&x,&y,&c); //c输入类型需要修改 addedge1(x,y,c); addedge2(y,x,c); //建反向边 } cin>>start>>end>>k; if(start==end) k++; //这题需要特殊处理 cout<<solve(start,end,k,n)<<endl; } return 0;}
- POJ 2449 Remmarguts' Date K最短路问题(单源点最短路径+A*算法)
- K最短路问题(单源点最短路径+A*算法)
- 【POJ】2449 Remmarguts' Date k短路(最短路径+A*)
- poj 2449 Remmarguts' Date(最短路+A*)
- POJ 2449 Remmarguts' Date(k限最短路)
- POJ 2449 Remmarguts' Date A*+spfa求第k最短路
- 单源点最短路径----Dijkstra算法
- 单源点最短路径(dijkstra算法)
- 单源点最短路径问题(Dijkstra算法)
- 最短路径(Dijkstra算法)也就是单源点问题!
- poj 2449 Remmarguts' Date(K短路,A*算法)
- POJ 2449 Remmarguts' Date [A*算法 K短路]
- POJ 2449 Remmarguts' Date (A*+K短路)
- POJ 2449 Remmarguts' Date(A*+SPFA)K短路问题
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- 单源点最短路径
- itoa 函数
- 判断IP的正则表达式
- struts2.3.14+spring3.1.1+hibernate4.1.0框架搭建新版SSH(下)
- day12线程间的通信,等待唤醒机制,生产者消费者问题。新锁lock(): 守护线程,interrupt()停止线程用,join()yield()
- CentOS VI常用命令
- POJ 2449 Remmarguts' Date K最短路问题(单源点最短路径+A*算法)
- px、dip、sp区别和使用方法
- Android中Service方式使用的理解
- javascript :简单的小技巧
- 解决硬盘文件系统raw问题
- linux解压 tar命令
- unity3d版本更新日志
- 微软面试100题系列-第1题
- tar命令的C参数