POJ 2449 求第K短路
第一道第K短路的题目 QAQ
拿裸的DIJKSTRA + 不断扩展的A* 给2000MS过了
题意:大意是 有N个station 要求从s点到t点 的第k短路 (不过我看题意说的好像是从t到s 可能是出题人写错了)
从这题中还真的学到了很多
1.第k短路的算法 A* 还有用边表实现dij
(注:以下部份资料来源于网上)
所谓A*就是启发是搜索 说白了就是给搜索一个顺序使得搜索更加合理减少无谓的搜索. 如何来确定搜索的顺序?..也就是用一个值来表示 这个值为f[n]..每次搜索取f[x]最小的拓展 那么这个f[n]=h[n]+g[n]
其中f(n) 是节点n的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。如果说详细 点,g(n)代表了搜索的广度的优先趋势。但是当h(n) >> g(n)时,可以省略g(n),而提高效率。
A*算法的估价函数可表示为:
f’(n) = g’(n) + h’(n)
这里,f’(n)是估价函数,g’(n)是起点到终点的最短路径值,h’(n)是n到目标的最短路经的启发值。由 于这个f’(n)其实是无法预先知道的,所以我们用前面的估价函数f(n)做近似。g(n)代替g’(n),但 g(n)>=g’(n) 才可(大多数情况下都是满足的,可以不用考虑),h(n)代替h’(n),但h(n)<=h’(n)才可(这一点特别的重 要)。可以证明应用这样的估价函数是可以找到最短路径的,也就是可采纳的。我们说应用这种估价函数的 最好优先算法就是
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm> #define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = ; struct vertex{
int sum, h, pos;
bool operator < (vertex a) const{
return a.sum + a.h < sum + h;
}
};
struct sc{
int u, v, w, next;
}line1[MAXN*MAXN],line2[MAXN*MAXN]; int link1[MAXN],link2[MAXN],h[MAXN],times[];
int n, m, s, e, k;
bool vis[MAXN];
priority_queue <vertex> que; void init(){
memset(link1, , sizeof(link1));
memset(link2, , sizeof(link2));
memset(vis,,sizeof(vis));
memset(h,0x3f,sizeof(h));//h函数初始值为最大
while (!que.empty()) que.pop();
memset(times,,sizeof(times));
} void djikstra(){
int i,k,p;
h[e] = ;
for (p = ; p <= n; ++p){
k = ;
for (i = ; i <= n; ++i)
if (!vis[i] && (!k||h[i]<h[k])) k = i;
vis[k] = true;
k = link2[k];
while (k){
if (h[line2[k].v] > h[line2[k].u] + line2[k].w)
h[line2[k].v] = h[line2[k].u] + line2[k].w;
k = line2[k].next;
}
}
} int Astar(){
int t;
vertex g,temp;
g.pos = s;
g.sum = ;
g.h = h[s];
que.push(g); if (s==e) ++k;
while (!que.empty()){
g = que.top();//每次取估价函数值最小的节点
que.pop();
++times[g.pos];
if (times[g.pos] == k && g.pos == e) return g.sum + g.h;
if (times[g.pos] > k) continue; t = link1[g.pos];
while (t){//扩展,并把其加入优先队列即openlist
temp.sum = g.sum + line1[t].w;
temp.h = h[line1[t].v];
temp.pos = line1[t].v;
que.push(temp);
t = line1[t].next;
}
}
return -;
} int main(){
int i, j;
while(cin >> n >> m){
init();
for (i = ; i <= m; ++i){
cin >> line1[i].u >> line1[i].v >> line1[i].w;
line1[i].next = link1[line1[i].u];//记录与节点u有直接边的节点
link1[line1[i].u] = i; line2[i].u = line1[i].v;
line2[i].v = line1[i].u;
line2[i].w = line1[i].w;
line2[i].next = link2[line2[i].u];
link2[line2[i].u] = i;
}
cin >> s >> e >> k;
djikstra();
cout << Astar() << endl;
}
return ;
}
POJ 2449 求第K短路的更多相关文章
- POJ 2449 Remmarguts' Date (K短路 A*算法)
题目链接 Description "Good man never makes girls wait or breaks an appointment!" said the mand ...
- poj 2449 Remmarguts' Date K短路+A*
题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- POJ 2449 Dijstra + A* K短路
这题一开始的思路应该是直接从源点进行BFS搜索K短路. 但这样的复杂度在点数和K的值增大后将会变得很大. 而A*算法则构造一个h(x),在进行BFS时,每次都抛出最小的h(x)从而使汇点的出队速度加快 ...
- poj 2449(A*求第K短路)
题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...
- A*算法的认识与求第K短路模板
现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...
- POJ 2499 A*求第K短路
DES就是给你一个图.然后给你起点和终点.问你从起点到终点的第K短路. 第一次接触A*算法. 题目链接:Remmarguts' Date 转载:http://blog.csdn.net/mbxc816 ...
- POJ 2449Remmarguts' Date 第K短路
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 29625 Accepted: 8034 ...
- aStar算法求第k短路
A*的概念主意在于估计函数,f(n)=g(n)+h(n),f(n)是估计函数,g(n)是n节点的当前代价,h(n)是n节点的估计代价:而实际中,存在最优的估计函数f'(n)=g'(n)+h'(n),那 ...
随机推荐
- cdoj 1134 男神的约会 状压dp
题目链接 给一个10*10的方格, 每个格子里面有0-9,走到一个格子, 就要在这个格子待一段时间, 时间长度为这个格子的数字. 从左上角走到右下角, 要求0-9必须每种格子都要走到, 输出最短时间. ...
- 关于yield创建协程的理解
先上利于理解的代码: #coding:utf-8 def consumer(): c_r = '' while 1: m = yield c_r if not m: return print(&quo ...
- Cubieboard 关闭板载led
修改script.bin 找到最后节点[led_para] 修改leds_used = 0 script.bin 一般在系统盘的第一个分区 例如nand就在/dev/nanda sdcard就在/d ...
- ASP.NET 使用My97DatePicker日期控件
首先要下载该控件的包,下载地址:http://pan.baidu.com/s/1Aa5gk 引用文件 <script src="js/My97DatePicker/WdatePicke ...
- MyEclipse 怎样手动编译整个项目
去掉自动编译的对勾,项目上就有build project,在菜单project->>build automatically. MyEclipse 菜单 Project->Build ...
- Android 通过Dom, Sax, Pull解析网络xml数据
这篇文章不是完全原创,XML解析的部分参考了 liuhe688 的文章.文章地址:http://blog.csdn.net/liuhe688/article/details/6415593 这是一个几 ...
- ACM_HDU 1231 最大连续子序列 (dp)_代码分析
Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i < ...
- BZOJ 1739: [Usaco2005 mar]Space Elevator 太空电梯
题目 1739: [Usaco2005 mar]Space Elevator 太空电梯 Time Limit: 5 Sec Memory Limit: 64 MB Description The c ...
- SpringMVC静态文件(图片)访问+js访问 简单小例子
项目文件布局: web.xml文件: <?xml version="1.0" encoding="UTF-8"?> <web-app vers ...
- config -导航
在config进行中配置 1在config中添加SITmap <siteMap enabled="true" defaultProvider="UserSiteM ...