POJ 2449(A*算法与最短路算法)
来源:互联网 发布:张大宇数据 编辑:程序博客网 时间:2024/06/05 23:50
题目描述:给定一个带权有向图,询问从起点到终点第k短路径长度,如果没有则输出-1。这个题目数据有特殊之处,就是如果起点与终点重合时,距离0并不算第一短最短路径。
A*算法:使用估值函数来进行搜索,f(n)=g(n)+h(n),其中f(n)表示状态起点经过状态n到状态终点的估值,g(n)为状态起点到状态n的距离值,h(n)为状态n到状态终点的距离值。之所以说f(n)是估值函数是因为,h(n)通常不是准确值而是估计值。该题的状态是(u,g,f)其中u表示当前在点u,且从状态起点到此状态的距离值为g,f是通过dis(u)+g计算得到。
其中dis(u)为点u到终点的最短距离。
每次扩展时使用f最小的状态。搜索时出现第k次终点t时,就能得出答案。
简单证明:f值最小即g+dis(u)最小,则当第一次出现终点t时,就是从起点到终点的最短路径。当舍弃最短路径后,继续扩展状态,可以想到当第二次出现终点t时,就是从起点到终点的第二短路径,所以可以求出第k小最短路径。
代码如下:
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <queue>using namespace std;const int maxn=1005;const int maxe=100005;struct State{ int f; int g; int u; bool operator<(const State b)const{ if(f==b.f)return g>b.g; return f>b.f; }};struct Edge{ int v; int w; int ne;}edge[maxe],reedge[maxe];int head[maxn],rehead[maxn];int dis[maxn],vis[maxn];int n,m;int cot;int s,t,k;void init(){ cot=0; memset(head,-1,sizeof(head)); memset(rehead,-1,sizeof(rehead));}void addedge(int u,int v,int w){ edge[cot].v=v; edge[cot].w=w; edge[cot].ne=head[u]; head[u]=cot; reedge[cot].v=u; reedge[cot].w=w; reedge[cot].ne=rehead[v]; rehead[v]=cot++;}void SPFA(){ queue<int>q; memset(vis,0,sizeof(vis)); memset(dis,-1,sizeof(dis)); int u,v; q.push(t); vis[t]=true; dis[t]=0; while(!q.empty()){ u=q.front(); q.pop(); for(int i=rehead[u];~i;i=reedge[i].ne){ v=reedge[i].v; if(dis[v]>dis[u]+reedge[i].w||dis[v]==-1){ dis[v]=dis[u]+reedge[i].w; if(!vis[v]){ q.push(v); vis[v]=true; } } } vis[u]=false; }}int Astart(){ if(s==t)k++; if(dis[s]==-1)return -1; int cnt=0; priority_queue<State>q; State a,b; a.g=0;a.u=s;a.f=a.g+dis[a.u]; q.push(a); while(!q.empty()){ b=q.top(); q.pop(); if(b.u==t){ cnt++; //printf("%d %d %d %d\n",b.f,b.g,b.u,dis[b.u]); if(cnt==k)return b.g; } for(int i=head[b.u];~i;i=edge[i].ne){ a.g=b.g+edge[i].w; a.u=edge[i].v; a.f=a.g+dis[a.u]; q.push(a); } } return -1;}int main(){ int u,v,w; while(scanf("%d %d",&n,&m)==2){ init(); for(int i=0;i<m;i++){ scanf("%d %d %d",&u,&v,&w); addedge(u,v,w); } scanf("%d %d %d",&s,&t,&k); SPFA(); /* for(int i=1;i<=n;i++){ printf("%d:%d\n",i,dis[i]); } */ printf("%d\n",Astart()); } return 0;}
0 0
- POJ 2449(A*算法与最短路算法)
- POJ 2449 Remmarguts' Date K最短路问题(单源点最短路径+A*算法)
- POJ 1094 最短路算法
- poj 1125(最短路算法)
- poj 2449 k短路+A*算法
- k短路 SPFA+A*算法 poj 2449
- k短路 SPFA+A*算法 poj 2449
- 最短路(dijkstra(迪杰斯特拉)算法,)A - 最短路
- POJ Stockbroker Grapevine(最短路算法)
- POJ-3268-最短路(dijkstra算法)
- POJ 2387 最短路Dijkstra算法
- poj 1125 floyd算法求最短路
- poj-1502(最短路dijkstra算法)
- poj2449 第k最短路,A*算法
- K最短路问题(A*算法)
- 求图的第K短路(A*算法与最短路的应用)
- poj 2449 Remmarguts' Date(K短路,A*算法)
- POJ 2449 Remmarguts' Date [A*算法 K短路]
- PHP分页函数代码(简单实用型)
- php使用cookie来保存用户登录信息
- Android绘图那些事儿(上)
- OpenGL-绘制点、线、面
- 网络基础篇——IP数据报格式及路由器报表算法
- POJ 2449(A*算法与最短路算法)
- 简单强大的xml解析器
- C++中函数参数的默认值和函数重载的冲突
- 第二章 java基础(常量类型)
- PAT乙级.1046. 划拳(15)
- 第二章 java基础(常量使用示例)
- FFmpeg中的滤镜(一):滤镜概念及命令规则
- Linux学习笔记--命令别名与历史命令
- c 语言中内存的动态分配(allocate)和释放(free)