K 短路问题(A* 启发式广搜)
1.k 短路问题就是最短路问题的延申,要找出第 k 短的路径。用广搜进行路径查找,第一次找到的 就是最短路,第二次找到的是第 2 短 路⋯以此类推。所以我们只需要一直广搜直到找到 k 次终 点,这时即为第 k 短路。
2.启发式搜索:又叫有信息的搜索,就是不像暴力搜索一样每次向外扩展一层,而是选取最有可能 到达终点的方式。
3. ** A* 算法 ** :是启发式搜索的一种算法,因为每次要选取最有可能到 达终点的方式,所以引入 估价函数,不同的启发式搜索有不同的估价函数定 义方式。A* 是以 f=g+h 来定义估价函数的。
g:当前状态已消耗的代价,是确定的。h:当前状态到目标状态的预估代价,是预估的,h 应根 据不同问题来确定。
4.在 k 短路问题中,一般以当前点到起点的距离为 g,以当前点到终点的最短路为 h。g 可以在执 行过程中逐步确定。而 h 则需要以终点为起点跑一次最短路,这样每个点到终点的最短路就求出 来了。

方法一:超出内存限制
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<list>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxx=1005;
const int inf=0x3f3f3f3f;
int dist[maxx];//从起点实际到终点的路径,为h(x)
int e[maxx][maxx];
int vis[maxx];//标记该点是否已经经过
int n,m;
int s,t;
struct node{int v,w;node(){}node(int vs=0,int ws=0):v(vs),w(ws){};bool operator<(const node&t)const{return w+dist[v]>t.w+dist[t.v];}
};struct edge{int v,w;edge(){}edge(int vs=0,int ws=0):v(vs),w(ws){};
};
vector<edge>rever[maxx];//反向存图,这样从终点找一次单源最短路即可求出dis
priority_queue<node>q;
queue<int>qs;
vector<int>G[maxx];void SPFA_min(int n,int u){memset(dist,inf,sizeof(dist));memset(vis,0,sizeof(vis));qs.push(u);vis[u]=1;dist[u]=0; while(!qs.empty()){int u=qs.front();qs.pop();vis[u]=0;for(int i=0;i<G[u].size();i++){int v=G[u][i];if(dist[v]>dist[u]+e[u][v]){dist[v]=dist[u]+e[u][v];if(vis[v]==0){qs.push(v);vis[v]=1;}}}}
}
int Astar(int s,int k){while(!q.empty()){q.pop();}q.push(node(s,0));k--;while(!q.empty()){node u=q.top();q.pop();int v=u.v;if(v==t){if(k){k--;}else{return u.w;}}for(int i=0;i<rever[v].size();i++){//将当前点所有能经过的点扔进优先队列int x=rever[v][i].v;int w=rever[v][i].w;//这里的g(x)我们取通过这条边的实际花费q.push(node(x,u.w+w));}}return -1;//没有搜索出第K短路
}
void add(int u,int v,int w){rever[u].push_back(edge(v,w));//反向存图 G[u].push_back(v);G[v].push_back(u);
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){for(int i=1;i<=n;i++){G[i].clear();}while(!q.empty()){q.pop();}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){e[i][j]=inf;}}for(int i=0;i<=n+2;i++){rever[i].clear();}for(int i=1;i<=m;i++){int a,b,cost;scanf("%d %d %d",&a,&b,&cost);e[a][b]=e[b][a]=cost;add(a,b,cost);}int k;scanf("%d %d %d",&s,&t,&k);SPFA_min(n,t);if(dist[s]==inf){cout<<-1<<endl;}else{if(s==t){k++; }cout<<Astar(s,k)<<endl;}}return 0;
}
方法二:超出内存限制
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<list>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxx=1005;
const int inf=0x3f3f3f3f;
int dist[maxx];//从起点实际到终点的路径,为h(x)
int e[maxx][maxx];
int vis[maxx];//标记该点是否已经经过
int n,m;
int s,t;
struct node{int v,w;node(){}node(int vs=0,int ws=0):v(vs),w(ws){};bool operator<(const node&t)const{return w+dist[v]>t.w+dist[t.v];}
};struct edge{int v,w;edge(){}edge(int vs=0,int ws=0):v(vs),w(ws){};
};
vector<edge>rever[maxx];//反向存图,这样从终点找一次单源最短路即可求出dis
priority_queue<node>q;
void Dijstra(int n,int u){memset(vis,0,sizeof(vis));memset(dist,inf,sizeof(dist));for(int i=1;i<=n;i++){dist[i]=e[u][i];}vis[u]=1;dist[u]=0;for(int i=1;i<n;i++){int temp=inf;int ts=u;for(int j=1;j<=n;j++){if(!vis[j]&&dist[j]<temp){temp=dist[j];ts=j;}}if(ts==u)break;vis[ts]=1;for(int j=1;j<=n;j++){if(!vis[j]&&dist[j]>dist[ts]+e[ts][j]){dist[j]=dist[ts]+e[ts][j];}}}
}
int Astar(int s,int k){while(!q.empty()){q.pop();}q.push(node(s,0));k--;while(!q.empty()){node u=q.top();q.pop();int v=u.v;if(v==t){if(k){k--;}else{return u.w;}}for(int i=0;i<rever[v].size();i++){//将当前点所有能经过的点扔进优先队列int x=rever[v][i].v;int w=rever[v][i].w;//这里的g(x)我们取通过这条边的实际花费q.push(node(x,u.w+w));}}return -1;//没有搜索出第K短路
}
void add(int u,int v,int w){rever[u].push_back(edge(v,w));//反向存图
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){for(int i=0;i<=n+2;i++){rever[i].clear();}for(int i=1;i<=m;i++){int a,b,cost;scanf("%d %d %d",&a,&b,&cost);e[b][a]=cost;add(a,b,cost);}int k;scanf("%d %d %d",&s,&t,&k);Dijstra(n,t);if(dist[s]==inf){cout<<-1<<endl;}else{if(s==t){k++; }cout<<Astar(s,k)<<endl;}}return 0;
}方法三:这个方法是看了网上的算法模版的(Accept)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<list>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxx=1005;
const int inf=0x3f3f3f3f;
int dist[maxx];//从起点实际到终点的路径,为h(x)
int vis[maxx];//标记该点是否已经经过
int n,m;
int s,t;
struct node{int v,w;node(){}node(int vs=0,int ws=0):v(vs),w(ws){};bool operator<(const node&t)const{return w+dist[v]>t.w+dist[t.v];}
};struct edge{int v,w;edge(){}edge(int vs=0,int ws=0):v(vs),w(ws){};
};
vector<edge>rever[maxx],e[maxx];//反向存图,这样从终点找一次单源最短路即可求出dis
priority_queue<node>q;
priority_queue<node>p;
void Dijstra(int n,int s){memset(vis,0,sizeof(vis));memset(dist,inf,sizeof(dist));while(!p.empty()){p.pop();}dist[s]=0;p.push(node(s,0));while(!p.empty()){node temp=p.top();p.pop();int u=temp.v;if(vis[u]){continue;}vis[u]=1;for(int i=0;i<e[u].size();i++){int v=e[u][i].v;int w=e[u][i].w;if(!vis[v]&&dist[v]>dist[u]+w){dist[v]=dist[u]+w;p.push(node(v,dist[v]));}}}
}
int Astar(int s,int k){while(!q.empty()){q.pop();}q.push(node(s,0));k--;while(!q.empty()){node u=q.top();q.pop();int v=u.v;if(v==t){if(k){k--;}else{return u.w;}}for(int i=0;i<rever[v].size();i++){//将当前点所有能经过的点扔进优先队列int x=rever[v][i].v;int w=rever[v][i].w;//这里的g(x)我们取通过这条边的实际花费q.push(node(x,u.w+w));}}return -1;//没有搜索出第K短路
}
void add(int u,int v,int w){rever[u].push_back(edge(v,w));//反向存图 e[v].push_back(edge(u,w));     //正向存图
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){for(int i=0;i<=n+2;i++){rever[i].clear();e[i].clear();}for(int i=1;i<=m;i++){int a,b,cost;scanf("%d %d %d",&a,&b,&cost);add(a,b,cost);}int k;scanf("%d %d %d",&s,&t,&k);Dijstra(n,t);if(dist[s]==inf){cout<<-1<<endl;}else{if(s==t){k++; }cout<<Astar(s,k)<<endl;}}return 0;
}方法四:不知道为什么怎么都没有找出该程序会出现runtime error
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<list>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxx=2005;
const int inf=0x3f3f3f3f;
int dist[maxx];//从起点实际到终点的路径,为h(x)
int vis[maxx];//标记该点是否已经经过
int n,m;
int s,t;
struct point{int x,y;int w;
}num[maxx];
struct node{int v,w;node(){}node(int vs=0,int ws=0):v(vs),w(ws){};bool operator<(const node&t)const{return w+dist[v]>t.w+dist[t.v];}
};
struct edge{int v,w;edge(){}edge(int vs=0,int ws=0):v(vs),w(ws){};
};
vector<edge>rever[maxx];//反向存图,这样从终点找一次单源最短路即可求出dis
priority_queue<node>q;
void Bellman_ford(int s){//Bellman_ford算法 memset(vis,0,sizeof(vis));memset(dist,inf,sizeof(dist));dist[s]=0;int flag=1;for(int i=1;i<=n-1;i++){flag=1;for(int j=1;j<=m;j++){if(dist[num[j].y]>dist[num[j].x]+num[j].w){dist[num[j].y]=dist[num[j].x]+num[j].w;flag=0;}}if(flag==1)break;}
}
int Astar(int s,int k){while(!q.empty()){q.pop();}q.push(node(s,0));k--;while(!q.empty()){node u=q.top();q.pop();int v=u.v;if(v==t){if(k){k--;}else{return u.w;}}for(int i=0;i<rever[v].size();i++){//将当前点所有能经过的点扔进优先队列int x=rever[v][i].v;int w=rever[v][i].w;//这里的g(x)我们取通过这条边的实际花费q.push(node(x,u.w+w));}}return -1;//没有搜索出第K短路
}
void add(int u,int v,int w){rever[u].push_back(edge(v,w));//反向存图
}
int main(){while(scanf("%d %d",&n,&m)!=EOF){for(int i=0;i<=n+2;i++){rever[i].clear();}for(int i=1;i<=m;i++){scanf("%d %d %d",&num[i].x,&num[i].y,&num[i].w);add(num[i].x,num[i].y,num[i].w);}int k;scanf("%d %d %d",&s,&t,&k);Bellman_ford(t);if(dist[s]==inf){cout<<-1<<endl;}else{if(s==t){k++; }cout<<Astar(s,k)<<endl;}}return 0;
}

poj2449(k短路算法)相关推荐

  1. 综合算法05—考虑换乘的K短路算法

    一.问题描述 在路网中,已知站点.线路和线路-站点数据,有条件: 1.考虑到换乘时要花费一定的时间,因此对换乘路径费用要加上换乘时间. 2.当路网复杂时,为了避免多余计算,定义有效路径,使得路径在有效 ...

  2. 浅谈K短路算法(KSP)之二(YEN .J算法求解)

    对于具有n个顶点和m条边且边的权值非负的简单图(无重边和环),K短路,是指的起点s到终点t的最短路径中第k个最小的.K短路分为有限制的K短路和无限制的K短路,有限制的K短路是指求得的路径中不含有回路( ...

  3. 浅谈K短路算法(KSP)之一(A*算法求解)

    对于具有n个顶点和m条边且边的权值非负的简单图(无重边和环),K短路,是指的起点s到终点t的最短路径中第k个最小的.K短路分为有限制的K短路和无限制的K短路,有限制的K短路是指求得的路径中不含有回路( ...

  4. 第k短路 算法详解(图解)与模板(A* 算法)

    本博文来自bestsort (转载请保留此信息) A*是一种启发式搜索,根据目标地点和当前点的距离和估计要走的步数来决策下一步走哪个方向.而这两个参数,一般用g(x)g(x)g(x)和h(x)h(x) ...

  5. ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven (K短路算法模板)

    题意 : 求第k短路的权值是否超过T(权值) 解法: 网上随便找的一个求K短路的算法模板套弄一下即可 (模板要好,不然邻接表存图会TLE , 网上换了两个模板才AC的) AC代码: #include& ...

  6. poj2449 K短路模板题

    昨晚看WC论文发现自己连K短路的经典A*算法还不会,补了一波,模板题输出-1后没return继续跑wa了一早上...... 算法流程: ①在反向图中求出t到每个点的最短路 ②从原点bfs,估价f=d+ ...

  7. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  8. 综合算法02—指定点之间的K短路

    %注意:程序中调用了Dijkstras算法,若需要运行,请自行将其放在同目录下. function [W_Section,Line_Section_01Mat,Mxf]=KSP(Road_Net,Li ...

  9. POJ--2449--Remmarguts#39; Date【dijkstra_heap+A*】第K短路

    链接:http://poj.org/problem?id=2449 题意:告诉你有n个顶点,m条边,并把这些边的信息告诉你:起点.终点.权值.再告诉你s.t.k.需求出s到t的第k短路,没有则输出-1 ...

最新文章

  1. python excel 教程推荐_python对Excel按条件进行内容补充(推荐)
  2. 深入理解C/C++二维数组
  3. Service 和 doGet 和 doPost 方法的区别
  4. INNODB的锁的类型
  5. 第十章 动态选路协议
  6. skywalking(4)
  7. phpcmsV9:后台无法选择模板
  8. [树状数组][哈希]JZOJ 3240 Seat
  9. vivado和modelsim联合仿真实现占空比1:15的分频
  10. linux kworker cpu,Kworker,它是什么,为什么它占用这么多 CPU?
  11. 思维模型 SWOT分析
  12. cocos2dx之Box2D
  13. TCP/IP第四章笔记ARP协议
  14. 给自己看的(摘自他人)
  15. python网络爬虫一
  16. Collada 快速入门
  17. springboot热部署该怎么实现?springboot热部署实现方式
  18. Win11正式发布,新功能炸裂!
  19. 购房从银行贷款d,准备每月还款p,月利率为r,计算多少月能还清。
  20. 【博客587】ipvs hook点在netfilter中的位置以及优先级

热门文章

  1. python⾯向对象学员管理系统
  2. ACMNO.21 C语言-逆序输出 输入10个数字,然后逆序输出。 输入 十个整数 输出 逆序输出,空格分开 样例输入 1 2 3 4 5 6 7 8 9 0
  3. 3D视觉检测的未来:光度立体技术
  4. 单镜头视觉系统检测车辆的测距方法
  5. hdu1874(畅通工程续)
  6. MVC Html.ActionLink Area 链接中含区域的页面之间的跳转
  7. Java 获取当前时间最近12个月(字符串)
  8. [Head First设计模式]身边的设计模式——适配器模式
  9. 第十五章 动态规划——最优二叉搜索树
  10. 邮件发送退信分析大全/SMTP error, RCPT TO: 550 Relay Deny