cogs 133. [USACO Mar08] 牛跑步 A*算法

by  http://blog.csdn.net/jarily/article/details/8871968/*
 *算法引入:
 *在单源点最短路径问题中,实际运用时还需知道最短路径外,次短路或者第三短路;
 *即要知道多条最短路,并排出其长度增加的顺序,即为K最短路问题;
 *
 *算法思想:
 *单源点最短路径+高级搜索A*;
 *A*算法结合了启发式方法和形式化方法;
 *启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大降低;
 *形式化方法不利用图给出的信息,而仅通过数学的形式分析;
 *
 *算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向;
 *当这条路径失败时,它会尝试其他路径;
 *对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个;
 *
 *对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度;
 *f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远;
 *
 *为了加速计算,h(p)需要在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源点最短路径就能得到每个点的h(p)了;
 *
 *算法步骤:
 *(1),将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离;
 *(2),新建一个优先队列,将源点s加入到队列中;
 *(3),从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数;
 *如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束;
 *否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;
 *
 *算法测试:
 *http://www.cogs.pro/cogs/problem/problem.php?pid=133
 *
 *题目大意:
 *求从s到t的第k短路的长度;
 */  

133. [USACO Mar08] 牛跑步

★★★   输入文件:cowjog.in   输出文件:cowjog.out   简单对比
时间限制:1 s   内存限制:128 MB

Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚.

Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bessie的牛棚;地点1是池塘.

很快, Bessie厌倦了一直走同一条路.所以她想走不同的路,更明确地讲,她想找出K(1<=K<=100)条不同的路经.为了避免过度劳累,她想使这K条路径为最短的K条路径.

请帮助Bessie找出这K条最短路经的长度.你的程序需要读入农场的地图, 一些从Xi到Yi的路径和它们的长度(Xi,Yi,Di). 所有(Xi,Yi,Di)满足(1<=Yi<Xi;Yi<Xi<=N,1<=Di<=1,000,000).

题目名称: cowjog

输入格式:

  • 第1行: 3个数: N,M,K
  • 第2..M+1行: 第 i+1行包含3个数 Xi,Yi,Di, 表示一条下坡的路.

样例输入 (cowjog.in):

5 8 7
5 4 1
5 3 1
5 2 1
5 1 1
4 3 4
3 1 1
3 2 1
2 1 1

输出格式:

  • 第1..K行: 第i行包含第i最短路径的长度,或?1如果这样的路径不存在.如果多条路径有同样的长度,请注意将这些长度逐一列出.

样例输出 (cowjog.out):

1
2
2
3
6
7
-1

输出解释:

路径分别为(5?1),(5?3?1),(5?2?1),(5?3?2?1),(5?4?3?1),(5?4?3?2?1)

代码:

/*
    k短路:
    建立反向图,计算终点到起点的单源最短路,最后A*求解最短路
    A*算法:
    新建一个优先队列,将源点s加入到队列中;
    从优先级队列中弹出估值函数f()最小的点p,如果点p就是t,则计算t出队的次数;
    f(n)=g(n)+h(n)  g(n) 表示走到当前点的路程
    h(n) 表示当前位置到终点的距离(在反向跑时已经计算出)
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>

using namespace std;
const int N=10010;
const int INF=9999999;

int head[N],head2[N],disf[N],ans[N];
int now1=1,now2=1,n,m,k,x,y,z,js;
bool vis[N];
struct zheng{
    int u,v,w,nxt;
}Z[N];
struct fang{
    int u,v,w,nxt;
}F[N];
struct node{
    int start,wei,will;
}now,nxt,topp;

inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘ || ch>‘9‘) {if(ch==‘-‘) f=-1;ch=getchar();}
    while(ch>=‘0‘ && ch<=‘9‘) {x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
    return x*f;
} 

inline void add(int u,int v,int w)
{Z[now1].v=v;Z[now1].w=w;Z[now1].nxt=head[u];head[u]=now1++;}

inline void add2(int u,int v,int w)
{F[now2].v=v;F[now2].w=w;F[now2].nxt=head2[u];head2[u]=now2++;}

bool operator < (node a,node b)
{return a.will>b.will;}

inline void spfa(int start)
{
    for(int i=1;i<=n;i++)
        disf[i]=INF;
    disf[start]=0;vis[start]=1;
    queue<int>q;
    q.push(start);
    while(!q.empty())
    {
        int topp=q.front();
        q.pop();
        vis[topp]=0;
        for(int i=head2[topp];~i;i=F[i].nxt)
            if(disf[F[i].v]>disf[topp]+F[i].w)
            {
                disf[F[i].v]=disf[topp]+F[i].w;
                if(!vis[F[i].v])
                    vis[F[i].v]=1,
                    q.push(F[i].v);
            }
    }
}

inline void Astart(int start,int endd)
{
    if(disf[start]==INF||start==endd)return ;
    priority_queue<node>q;
    now.start=start;now.wei=0;now.will=disf[start];
    q.push(now);
    while(!q.empty())
    {
        topp=q.top();
        q.pop();
        if(topp.start==endd)
        {
            ans[++js]=topp.wei;
            if(js==k)return ;
        }
        for(int i=head[topp.start];~i;i=Z[i].nxt)
        {
            nxt.start=Z[i].v;nxt.wei=topp.wei+Z[i].w;
            nxt.will=nxt.wei+disf[Z[i].v];
            q.push(nxt);
        }
    }
}

int main()
{
    freopen("cowjog.in","r",stdin);
    freopen("cowjog.out","w",stdout);
    n=read();m=read();k=read();
    for(int i=1;i<=n;i++)head[i]=head2[i]=-1;
    for(int i=1;i<=m;i++) x=read(),y=read(),z=read(),add(x,y,z),add2(y,x,z);
    spfa(1);//反向边的最短路
    Astart(n,1);
    for(int i=1;i<=js;i++)printf("%d\n",ans[i]);
    for(int i=js+1;i<=k;i++)printf("-1\n");
    return 0;
}
/*
5 8 7
5 4 1
5 3 1
5 2 1
5 1 1
4 3 4
3 1 1
3 2 1
2 1 1
*/
时间: 2024-11-10 13:43:33

cogs 133. [USACO Mar08] 牛跑步 A*算法的相关文章

COGS 133. [USACO Mar08] 牛跑步

★★★   输入文件:cowjog.in   输出文件:cowjog.out   简单对比时间限制:1 s   内存限制:128 MB Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bess

[USACO Mar08] 牛跑步 --k短路

[USACO Mar08] 牛跑步 Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<=1000)标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是Bessie的牛棚;地点1是池塘. 很快, Bessie厌倦了一直走同一条路.所以她想走不同的路,更明确地讲

[USACO Mar08] 牛跑步

http://www.cogs.pro/cogs/problem/problem.php?pid=133 ★★★   输入文件:cowjog.in   输出文件:cowjog.out   简单对比时间限制:1 s   内存限制:128 MB Bessie准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. Bessie也不想跑得太远,所以她想走最短的路经. 农场上一共有M(1<=M<=10,000)条路,每条路连接两个用1..N(1<=N<

牛跑步

133. [USACO Mar08] 牛跑步 ★★★   输入文件:cowjog.in   输出文件:cowjog.out   简单对比时间限制:1 s   内存限制:128 MB $Bessie$准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘,然后走回牛棚. $Bessie$也不想跑得太远,所以她想走最短的路经. 农场上一共有$M (1 <= M <= 10,000)$条路,每条路连接两个用$1..N(1 <= N <= 1000)$标号的地点.

USACO抓牛catchcow (bfs)

这题是黄巨大出的比赛题. http://poj.org/problem?id=3278 Description Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤

bzoj 1598: [Usaco2008 Mar]牛跑步 -- 第k短路,A*

1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MB Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. BESSIE也不想跑得太远,所以她想走最短的路经. 农场上一共有M (1 <= M <= 10,000)条路, 每条路连接两个用1..N(1 <= N <= 1000)标号的地点. 更方便的是,如果X>Y,则地点X

【USACO】奶牛跑步2

P1443 - [USACO]奶牛跑步2 Description FJ的N(1 <= N <= 100,000)头奶牛们又兴高采烈地出来运动了!她们在一条无限长的小路上跑步,每头牛起跑的位置都不同,速度也不尽相同. 道路中划出了若干条跑道,以便她们能快速"超车",同一跑道中的任意两头牛都不会出现在相同的位置.不过FJ不愿让任何一头牛更换跑道或者调整速度,他想 知道如果让牛们跑足T(1 <= T <= 1,000,000,000)分钟的话,至少需要多少条跑道才能满

七牛的存储算法猜测

个人浏览网页的时候,有打标签的习惯.最近整理以往的标签的时候,发现积累了一些有关七牛公司存储策略的网页,遂决定整理一篇文章处理,以备记忆.当然,也希望对他人有用. 因为七牛公司的存储策略主要基于纠删码(Erasure Codes,EC),所以下面先从纠删码引申开来. 引言:何为纠删码 数据的爆炸式增长使得存储系统的规模不断增加,存储设备的可靠性却一直没有得到显著提高(SSD 从SLC 到MLC 和TLC 可靠性不断下降,磁盘随着单位面积写入数据更多导致可靠性无法提升),从而给数据的持久化存储带来

【BZOJ1598】牛跑步 [A*搜索]

牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description BESSIE准备用从牛棚跑到池塘的方法来锻炼. 但是因为她懒,她只准备沿着下坡的路跑到池塘, 然后走回牛棚. BESSIE也不想跑得太远,所以她想走最短的路经. 农场上一共有M 条路, 每条路连接两个用1..N标号的地点. 更方便的是,如果X>Y,则地点X的高度大于地点Y的高度. 地点N是BESSIE的牛棚;地点1是池塘. 很快, B