POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
题目大意:给你一个有向图,并给你三个数s、t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径。如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度。
解题思路:这道题是一道简单的启发式搜索题目。而启发式搜索中A星算法是比较好理解的。A星算法中需要用到一个估价函数:f(n) = g(n)+ h(n)。其中,g(n)是当前量,h(n)是估计量,两者之和 f(n) 是估计值 。在这道题中,g(n)是从起点 s 到 点n 的已走距离,h(n)是从点n 到终点 t 的最短距离(dis[ n ]) 。每当我们走到一个点 tn 时 ,就计算出此时 tn 的g(tn) 、 h(tn)和 f(tn),把 tn 的这些信息压入一个队列,然后下一步选取队列中 f 值最小的节点作为下一步搜索的起点,如此反复,当我们第k次搜索到终点 t 时 ,这时g(t)的值就是我们要求的值。
Ps:这里我们需要用到优先队列,并且要注意:因为必须离开 s 点再返回,所以,当 s == t 时 ,k ++ 。
请看代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<cstdio>
#include<queue>
#define mem(a , b) memset(a , b , sizeof(a))
using namespace std ;
inline void RD(int &a)
{
a = 0 ;
char t ;
do
{
t = getchar() ;
}
while (t < '0' || t > '9') ;
a = t - '0' ;
while ((t = getchar()) >= '0' && t <= '9')
{
a = a * 10 + t - '0' ;
}
}
inline void OT(int a)
{
if(a >= 10)
{
OT(a / 10) ;
}
putchar(a % 10 + '0') ;
}
const int N = 1005 ;
const int M = 1e5 + 5 ;
const int INF = 0x7fffffff ;
struct Edge
{
int adj ;
int d ;
int next ;
} E[M * 3] ;
int head[N] ;
int headN[N] ; // 反向图
int dis[N] ;
bool inq[N] ;
int s , t , k ;
int n , m ;
int ce ;
void chu()
{
mem(head , - 1) ;
mem(headN , -1) ;
mem(inq , 0) ;
ce = 0 ;
}
void init()
{
chu() ;
int i ;
for(i = 0 ; i < m ; i ++)
{
int a , b , c ;
scanf("%d%d%d" , &a , &b , &c) ;
ce ++ ;
E[ce].adj = b ;
E[ce].d = c ;
E[ce].next = head[a] ;
head[a] = ce ; ce ++ ;
E[ce].adj = a ;
E[ce].d = c ;
E[ce].next = headN[b] ;
headN[b] = ce ;
}
scanf("%d%d%d" , &s , &t , &k) ;
}
queue<int> q ;
void spfa() // 计算 dis
{
while (!q.empty()) q.pop() ;
q.push(t) ;
inq[t] = true ;
int v ;
while (!q.empty())
{
v = q.front() ;
q.pop() ;
inq[v] = false ;
int i ;
for(i = headN[v] ; i != -1 ; i = E[i].next)
{
int tv = E[i].adj ;
int td = E[i].d ;
if(dis[v] + td < dis[tv])
{
dis[tv] = dis[v] + td ;
if(!inq[tv])
{
q.push(tv) ;
inq[tv] = true ;
}
}
}
}
}
struct F
{
int Node ;
int f ;
int g ;
int h ;
};
struct cmp
{
bool operator () (F a , F b)
{
if(a.f == b.f)
{
return a.g > b.g ;
}
return a.f > b.f ;
}
} ;
priority_queue<F, vector<F> , cmp> mq ;
int SP() // A星 算法
{
if(s == t) k ++ ;
while (!mq.empty()) mq.pop() ; // 注意队列要清空
int cnt = 0 ;
F u ;
u.Node = s ;
u.g = 0 ;
u.h = dis[s] ;
u.f = u.g + u.h ;
mq.push(u) ;
while (!mq.empty())
{
F v = mq.top() ;
if(v.Node == t)
{
cnt ++ ;
if(cnt == k)
{
return v.g ;
}
}
mq.pop() ;
int i ;
for(i = head[v.Node] ; i != -1 ; i = E[i].next)
{
int tv = E[i].adj ;
int td = E[i].d ;
F tmp ;
tmp.Node = tv ;
tmp.g = v.g + td ;
tmp.h = dis[tv] ;
tmp.f = tmp.g + tmp.h ;
mq.push(tmp) ;
}
}
return -1 ; // 注意:因为此图是有向图,所以K短路可能不存在!!!
}
void solve()
{
int i ;
for(i = 1 ; i <= n ; i ++)
{
dis[i] = INF ;
}
dis[t] = 0 ;
spfa() ;
if(dis[s] == INF)
{
puts("-1") ;
return ;
}
else
{
printf("%d\n" , SP()) ;
}
}
int main()
{
while (scanf("%d%d" , &n , &m) != EOF)
{
init() ;
solve() ;
}
return 0 ;
}
POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang的更多相关文章
- 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短路问题 Dijkstra+A*)
http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 25216 Accepted: 6882 ...
- poj 2449 Remmarguts' Date (k短路模板)
Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS Memory Limit: 65536K Total Subm ...
- poj 2449 Remmarguts' Date 第k短路 (最短路变形)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 33606 Accepted: 9116 ...
- POJ 2449 Remmarguts' Date (第k短路径)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions:35025 Accepted: 9467 ...
- poj 2449 Remmarguts' Date(K短路,A*算法)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013081425/article/details/26729375 http://poj.org/ ...
- POJ 2449 Remmarguts' Date ( 第 k 短路 && A*算法 )
题意 : 给出一个有向图.求起点 s 到终点 t 的第 k 短路.不存在则输出 -1 #include<stdio.h> #include<string.h> #include ...
- POJ 2449 Remmarguts' Date(第k短路のA*算法)
Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...
随机推荐
- (转徐明吉)C#生成随机数
private static char[] constant = { ', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p ...
- SharePoint中获取当前登录的用户名几种方式
第一种方法: System.Web.HttpContext.Current.User.Identity.Name.ToString();或者: SPContext.Current.Site.OpenW ...
- ASP.NET中的SQL注入攻击与防护
什么是SQL注入攻击? 它是在执行SQL查询的时候,由于接收了用户的非法参数从而导致,所执行的SQL语义与业务逻辑原本所要查询的语义不相符,从而实现的攻击. 例如我们经常使用的用户登录,通常会出现这样 ...
- Ecshop布局参考图
文章列表页: article_cat.dwt 文章内容页: article.dwt 商品品牌页: brand.dwt 所有分类页: catalog.dwt 商品列表页: category.dwt 商品 ...
- HTML5 canvas中的路径方法
路径方法 fill() 填充当前绘图(路径) stroke() 绘制已定义的路径 begin ...
- Input File 表单上传按钮美化
HTML <div class="input-file-button"> 上传图片<input type="file" class=" ...
- idHTTP最简洁的修改和取得Cookie例子
procedure TForm1.Button1Click(Sender: TObject); var HTTP: TidHTTP; html, s: string; i: integer; begi ...
- scrapy1.1入门用例简介-2
写一个小的scrapy project,爬取相关网页内容并保存为.json文件 0.创建project,genspider等. 1.修改items.py,内容如下: 2.修改dmoz.py,内容如下: ...
- 如何使用sublime编辑器运行python程序
现在越发喜欢sublime编辑器了,不仅界面友好美观.文艺,可扩展性还特别强. sublime本身是不具备运行python程序的能力的,需要做些设置才可以.以下是安装好sublime后设置的步骤: 点 ...
- IE10的bug?disabled button如何触发事件
最近碰到一个问题,IE10下的,貌似是个bug,求助! 问题表现为:在内部有dom元素的情况下,disabled状态的button会因为子元素的mouseover产生事件冒泡而触发,也就是说,disa ...