称号:poj 2449 Remmarguts' Date

意甲冠军:给定一个图,乞讨k短路。

算法:SPFA求最短路 + AStar

以下引用大牛的分析:

首先,为了说话方便,列出一些术语:

启示式搜索中,对于每一个状态 x。启示函数 f(x) 一般是这种形式:

f(x) = g(x) + h(x)

当中 g(x) 是从初始状态走到 x 所花的代价;h(x)
是从 x 走到目标状态所须要的代价的预计值。

相对于 h(x)。另一个概念叫 h*(x),表示从 x 走到目标状态所须要的实际最小代价(当然,这个值有时我们是事先无法知道的)。

假设在你的启示函数里,能保证 h(x) <= h*(x)。也就是说,你不能高估了从 x 走到目标状态所须要的代价,那就能够说这个搜索是 A* 算法(这里的“*”,英文就读作 star)。

A* 算法的特点是,假设存在从初始状态走到目标状态的最小代价的解。那么用 A* 算法搜索时,第一个找到的解就一定是最小代价的。这就是所谓的可採纳(admissible)。

1. 求前 K 短的 能够带环的 路径(的长度)

1.1. 典型的启示式搜索

设起点为 s;终点为 t。对于一个点 v,dt(v) 表示从 v 走到 t 的最短路径的长度(能够在初始化的时候全都算好)。

能够用最典型的启示式搜索来解这个问题。

一个状态 x 表示的是从 s 走到某个点的一条路径。把这个点记作 x.v,把这条路径的长度记作 x.len。接着。我们能够使用下面启示函数:

g(x) = x.len;  h(x) = dt(x.v);

∴ f(x) = g(x) + h(x) = x.len + dt(x.v)

初始状态中。 x.v = s; x.len
= 0。

然后每次让优先队列(所谓的 Open
表)中 f(x) 值最小的状态 x
出队,再跟据图中全部从 x.v 出发的边发展下一层状态,让它们进队列。优先队列中不存在判反复的问题,由于每一个状态所代表的路径肯定是不一样的。

不难想通,这是一个 A* 算法。由于这里的 h(x) 本身就是 h*(x),当然满足 h(x) <= h*(x)。

因此能够说,在每次出队列的状态 x 中,第一次遇到 x.v == t 时。就找到了从 s 到 t 的第一短的路径,它的长度就是 f(x)……第 k 次遇到 x.v == t 时,就找到了从 s 到 t 的第 k 短的路径。

这就是传说中的启示式搜索,由于有启示函数,并且可以利用广搜的特性,不断的扩展。

感觉是一个非常经典的题目。

注意的是,假如起点和终点是同一点,由于第一次走到的就是,所以必须K++

继续膜拜大牛,上我写的挫代码:

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int N = 1200;
const int inf = 0x3f3f3f3f;
struct Node
{
int to,val;
};
vector<Node> g[N],rg[N];
int dis[N];
bool vis[N];
int n,m;
void SPFA(int src)
{
int i;
memset(dis,inf,sizeof(dis));
dis[src] = 0;
queue<int> Q;
Q.push(src);
while(!Q.empty())
{
int u,v;
u = Q.front();
Q.pop();
for(int i = 0;i<g[u].size();i++)
{
v = g[u][i].to;
if(dis[v]>dis[u]+g[u][i].val) //记得这里这样写 最后改一下vis
{
dis[v] = dis[u] + g[u][i].val;
Q.push(v);
}
}
}
}
struct Tree
{
int v,len,h;
bool operator < (const Tree & a) const
{
return a.h<h;
}
};
priority_queue<Tree> que;
int Astar(int s,int t,int k)
{
int cnt = 0;
while(!que.empty())
que.pop();
if(s==t)
k++;
if(dis[s]==inf)
return -1;
Tree no,next;
no = (Tree){s,0,dis[s]};
que.push(no);
while(!que.empty())
{
no = que.top();
que.pop();
//printf("%d %d %d \n",no.v,no.len,no.h);
if(no.v == t)
cnt++;
if(cnt==k)
return no.len;
for(int i=0;i<rg[no.v].size();i++)
{
Node tmp = rg[no.v][i];
next.v = tmp.to;
next.len = no.len + tmp.val;
next.h = next.len + dis[tmp.to];
que.push(next);
}
}
return -1;
}
void Clear(int x)
{
for(int i=0;i<=x;i++){
g[i].clear();
rg[i].clear();
}
}
int main()
{
//freopen("Input.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
g[y].push_back((Node){x,z});
rg[x].push_back((Node){y,z});
}
int s,t,k;
scanf("%d%d%d",&s,&t,&k);
SPFA(t);
int ans = Astar(s,t,k);
printf("%d\n",ans);
Clear(n);
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意,不得转载。

poj 2449 Remmarguts&#39; Date 【SPFA+Astar】【古典】的更多相关文章

  1. poj 2449 Remmarguts' Date (k短路模板)

    Remmarguts' Date http://poj.org/problem?id=2449 Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  2. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  3. POJ——2449 Remmarguts' Date

    Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...

  4. poj 2449 Remmarguts' Date 求第k短路 Astar算法

    =.=好菜 #include <iostream> #include <cstdio> #include <string.h> #include <cstri ...

  5. POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang

    题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...

  6. poj 2449 Remmarguts' Date K短路+A*

    题目链接:http://poj.org/problem?id=2449 "Good man never makes girls wait or breaks an appointment!& ...

  7. 图论(A*算法,K短路) :POJ 2449 Remmarguts' Date

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 ...

  8. poj 2449 Remmarguts' Date 第k短路 (最短路变形)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 33606   Accepted: 9116 ...

  9. POJ 2449 Remmarguts' Date

    Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30725   Accepted: 8389 Description &quo ...

随机推荐

  1. 采用objdump调试驱动程序

    最近的一个推断调整nand是好是坏司机+测试程序,因此,与下面的调整过程.看来他也学到了一点知识.因此,关于备案. 这篇文章主要是讲述调式驱动的一个方法而已. 先来看看測试程序 #include &l ...

  2. Apple Watch 1.0 开发介绍 1.4 简介 使用iOS技术

    WatchKit extension可以使用iOS app同样的技术,但是由于他是extension,使用有些技术的时候会有限制,有些不推荐使用.下面是一些介绍以及什么时候使用什么技术: 有些需要权限 ...

  3. 自己写CPU第四阶段(2)——验证该第一指令ori实现效果

    我们会继续上传新书<自己写CPU>(未公布),今天是12片,四篇 书名又之前的<自己动手写处理器>改为<自己动手写CPU> 4.3 验证OpenMIPS实现效果 4 ...

  4. mysql声明摘要

    前一段时间,和学生参加该项目的最终完成,主要的项目是做一个报告,它涉及到很多sql声明,因此,采取下一个汇总. 一.基金会 1.数据库相关的命令 a>.创建数据库 CREATE DATABASE ...

  5. UVa11488-Hyper Prefix Sets(trie树)

    H Hyper Prefix Sets Prefix goodness of a set string is length of longest common prefix*number of str ...

  6. SVN命令汇总

    1.将文件checkout到本地文件夹  svn checkout path(path是server上的文件夹)  比如:svn checkout svn://192.168.1.1/pro/doma ...

  7. 编hadoop-1.X源代码

    满足需要在不久的将来windows调试Linux下一个hadoop问题,Linux检查时需要的文件权限.和windows在没有必要,因此,有必要修改hadoop源代码,再次编译,过程例如以下: (1) ...

  8. secureCRT使用退格键(backspace)出现^H解决的方法

    刚新装了python-3.4.1,使用secureCRT连接上去,可是我在进入后,输入回格键时,屏幕显示的是^H,这个让人受不了.最终在网上找到了解决的方法,仅仅要改动一下secureCRT的配置就可 ...

  9. 创建您自己的Maven模板

    相关链接: http://maven.apache.org/archetype/maven-archetype-plugin/ 一.事实上Maven的模板也是一个maven项目,所以我们首先要生成一个 ...

  10. UVA 12538 Version Controlled IDE 解题报告

    题意:给三种操作 1.在p位置插入一个字符串. 2.从p位置开始删除长度为c的字符串 3.输出第v个历史版本中从p位置开始的长度为c的字符串 解法:可以用平衡树做,但是不会.后来又听说可一用一个叫ro ...