次短路,第k最短路,有限制的最短路问题总结
来源:互联网 发布:小米 禁止安装软件 编辑:程序博客网 时间:2024/05/18 01:12
在这求第k短路用的是,A*+dij所谓的A*是一种启发式搜索,他给搜索选定一定的方向,避免了无谓的搜索,如何来确定搜索的顺序?也就是用一个值来表示这个值为f[x],每次搜索取f[x]最小的拓展,那么这个f[x]=h[x]+g[x]其中这个h[x]就是当前搜索时的代价,如求K段路这个就是前一个点的h[x']+边的长度,而g[x]是一个估价函数,估价函数要小于是对当前点到目标的代价的估计,这个估计必须小于等于实际值,否则会出错。A*的关键也就是构造g[x],我们的dij算法。最短路就是一种A*搜索,其中g[x]=0。
而这里要说的求K短路一种方法,就是用BFS+A*来搜索的过程,g[x]的设定为到这个点到目标点的最短路(这个可以用dij一次求出)径,显然其实小于等于实际值的,h[x]就是搜索到这个点的代价(及走过的路程),用一个优先队列来做,每次取出h[x]+g[x]最小的点来拓展。拓展,也就是通过这点来更新其能直接经过一条边到达的点,这里做好一个新点就丢进优先队列里去,反正总会从对首弹出h[x]+g[x]最小的点。
首先,我们在放优先队列的是这样的节点,他包括,从原点到达本节点的路径长度len,然后我们在优先列里,按照len+dis[i](dis到达终点的最短路)的最小,优先级排队,那么当我们第一次搜索到E点时,这时肯定是最短路径,第二次取出的,就是第二短路,以此类推,从而可以求出第k短路。
struct cnode{ int u; int len; cnode (int uu,int ww):u(uu),len(ww){} friend bool operator < (cnode a,cnode b) { return a.len+dis[a.u]>b.len+dis[b.u]; }};
我们从一个点,如何扩展下一个点呢,就是将与相连的点,入队列(这样就会走重复的边),队列里面的节点就是,原点经过len的路经所到达的状态
int A_star(int s){ int i; if(dis[s]==inf)return -1;//这个一定要有,若s到t不连通的话,下面会 死循环 priority_queue<cnode>que; CL(tol,0); que.push(cnode(s,0)); while(!que.empty()) { cnode a=que.top();que.pop(); int u=a.u; int len=a.len; tol[u]++; if(tol[t]==k)return len; for(i=0;i<g[u].size();i++) { node b=g[u][i]; int v=b.u; que.push(cnode(v,len+b.w)); } } return -1;}
那要是本身就不存在K短路呢?那就是e拓展不到K但是其他点很有可能一直打圈圈无限下去,这里就要用个条件来判断一 下。首先在找某个点作为优先队列头出现了几次就用了一个计数器times[],所求的点times[e]==k就代表得到了解,如果当前想拓展的点times[]>k就没必要拓展了,因为这个点已经是求到k+1短路了,从这个点继续往下搜肯定得到的是大于等于k+1短路的路径,就像1->2有3条路,2->3有2条路,那1->3有6条路的概念差不多,没必要对其进行拓展了。
注意 :若是有向边时,我们求到终点的最短距离时,要将边反向。
poj 2449 Remmarguts' Date (有向边)
http://poj.org/problem?id=2449
求任意两点的第k短路
#include<functional>#include<algorithm>#include<iostream>#include<fstream>#include<sstream>#include<iomanip>#include<numeric>#include<cstring>#include<climits>#include<cassert>#include<cstdio>#include<string>#include<vector>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<list>#include<set>#include<map>using namespace std;#define CL(a,num) memset(a,num,sizeof(a));#define inf 9999999#define maxn 1030#define eps 1e-6struct node{ int u; int w; node (int uu,int ww):u(uu),w(ww){}};vector<node>g[maxn],rg[maxn];int dis[maxn],vis[maxn],tol[maxn];struct cnode{ int u; int len; cnode (int uu,int ww):u(uu),len(ww){} friend bool operator < (cnode a,cnode b) { return a.len+dis[a.u]>b.len+dis[b.u]; }};int n,m,s,t,k;void spfa(int s){ int i; for(i=0;i<=n;i++) { dis[i]=inf; vis[i]=0; } dis[s]=0; queue<int>que; que.push(s); while(!que.empty()) { int u=que.front();que.pop(); vis[u]=0; for(i=0;i<rg[u].size();i++) { node b=rg[u][i]; int v=b.u; if(dis[v]>dis[u]+b.w) { dis[v]=dis[u]+b.w; if(!vis[v]) { vis[v]=1; que.push(v); } } } }}int A_star(int s){ int i; if(dis[s]==inf)return -1; priority_queue<cnode>que; CL(tol,0); que.push(cnode(s,0)); while(!que.empty()) { cnode a=que.top();que.pop(); int u=a.u; int len=a.len; tol[u]++; if(tol[t]==k)return len; for(i=0;i<g[u].size();i++) { node b=g[u][i]; int v=b.u; que.push(cnode(v,len+b.w)); } } return -1;}int main(){ int i,x,y,z; while(scanf("%d %d",&n,&m)!=EOF) { for(i=0;i<=n;i++)g[i].clear(); for(i=0;i<m;i++) { scanf("%d %d %d",&x,&y,&z); g[x].push_back(node(y,z)); rg[y].push_back(node(x,z)); } scanf("%d %d %d",&s,&t,&k); if(s==t)k++; spfa(t); int ans=A_star(s); printf("%d\n",ans); } return 0;}
poj 3255 Roadblocks
求1到n的次短路
#include<functional>#include<algorithm>#include<iostream>#include<fstream>#include<sstream>#include<iomanip>#include<numeric>#include<cstring>#include<climits>#include<cassert>#include<cstdio>#include<string>#include<vector>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<list>#include<set>#include<map>#define CL(a,num) memset(a,num,sizeof(a));#define inf 9999999#define maxn 5030#define eps 1e-6using namespace std;int n,k,m;int dis[maxn],tol[maxn],vis[maxn];struct node{ int u; int w; node (int uu,int ww):u(uu),w(ww){}};vector<node>g[maxn];struct anode{ int u; int len; anode(int uu,int w):u(uu),len(w){} friend bool operator < (anode a, anode b) { return a.len+dis[a.u]>b.len+dis[b.u]; }};void SPFA(int x){ int i; for(i=0;i<=n;i++) { dis[i]=inf; vis[i]=0; } dis[n]=0; queue<int>que; que.push(n); vis[n]=1; while(!que.empty()) { int u=que.front();que.pop(); vis[u]=0; for(i=0;i<g[u].size();i++) { node b=g[u][i]; int v=b.u; if(dis[v]>dis[u]+b.w) { dis[v]=dis[u]+b.w; if(!vis[v]) { vis[v]=1; que.push(v); } } } }}int A_star(int s){ int i; if(dis[s]==inf)return -1; priority_queue<anode>que; CL(tol,0); que.push(anode(1,0)); while(!que.empty()) { anode a=que.top();que.pop(); int u=a.u; int len=a.len; tol[u]++; if(tol[n]==k)return len; for(i=0;i<g[u].size();i++) { node b=g[u][i]; int v=b.u; que.push(anode(v,len+b.w)); } } return -1;}int main(){ int i,x,y,z; scanf("%d %d",&n,&m); k=2; for(i=0;i<m;i++) { scanf("%d %d %d",&x,&y,&z); g[x].push_back(node(y,z)); g[y].push_back(node(x,z)); } SPFA(n); int ans=A_star(1); printf("%d\n",ans); return 0;}
poj 3767 I Wanna Go Home (有限制的最短路)
#include<functional>#include<algorithm>#include<iostream>#include<fstream>#include<sstream>#include<iomanip>#include<numeric>#include<cstring>#include<climits>#include<cassert>#include<cstdio>#include<string>#include<vector>#include<bitset>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<list>#include<set>#include<map>#define CL(a,num) memset(a,num,sizeof(a));#define inf 9999999#define maxn 1030#define eps 1e-6using namespace std;int n,m;int mat[maxn][maxn],vis[maxn],pre[maxn],f[maxn],dis[maxn];void init(){ for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) mat[i][j]=inf; }}void dij(){ int i,j,k; for(i=0;i<=n;i++) { dis[i]=inf; vis[i]=0; pre[i]=0; } dis[1]=0; pre[1]=1; for(i=0;i<n;i++) { int min=inf; for(j=1;j<=n;j++) { if(!vis[j]&&dis[j]<min) { min=dis[j]; k=j; } } vis[k]=1; for(j=1;j<=n;j++) { if(!vis[j]&mat[k][j]!=inf&&dis[j]>dis[k]+mat[k][j]) dis[j]=dis[k]+mat[k][j]; } }}int main(){ int i,x,y,z,a,j; while(scanf("%d",&n),n) { scanf("%d",&m); init(); for(i=1;i<=m;i++) { scanf("%d %d %d",&x,&y,&z); mat[x][y]=mat[y][x]=z; } for(i=1;i<=n;i++) { scanf("%d",&f[i]); } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(f[i]!=f[j]) { if(f[i]==1&&f[j]==2) mat[j][i]=inf; else if(f[j]==1&&f[i]==2) mat[i][j]=inf; } } } dij(); if(dis[2]!=inf) printf("%d\n",dis[2]); else printf("-1\n"); } return 0;}
- 次短路,第k最短路,有限制的最短路问题总结
- 最短路 & 次短路
- pku2449第K短路 最短路+A*
- poj2449 第k短路....A*+最短路
- 有限制最短路hdu4179
- hdu4396 spfa有限制的最短路
- poj 1062(有限制的最短路)
- poj 1724(有限制的最短路)
- hdu4885 有 限制的最短路
- POJ1062(有限制的最短路)
- 最短路问题总结
- 第K最短路程序
- poj3463 最短路+次短路
- 最短路及次短路
- 【学/复习记录】最/次/k短路
- hdu3191 次最短路
- hdu4179 限制最短路
- dijkstra+限制最短路
- 深入浅出了解Struts的处理流程(有图有真相)
- Unity3d与eclipse协同工作环境
- Ubuntu 12.04 搭建 Eclipse Android 开发环境
- USB入门系列之六 —— USB设备的枚举过程
- jenkins 必须用到的下载地址链接
- 次短路,第k最短路,有限制的最短路问题总结
- smarty模板中判断数组为空方法
- 多线程面试题一
- 窗口滚动
- Floyd算法的总结
- 《『若水新闻』客户端开发教程》——01.课程介绍
- USB入门系列之七 —— USB的描述符及各种描述符之间的依赖关系
- 编程实现后台打印
- 类文件中访问Session,Request,Response