zoukankan      html  css  js  c++  java
  • 牛跑步

    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$条最短路经的长度.你的程序需要读入农场的地图, 一些从$X_i$到$Y_i$的路径和它们的长度$(X_i, Y_i, D_i)$. 所有$(X_i, Y_i, D_i)$满足$(1 <= Y_i < X_i; Y_i < X_i <= N, 1 <= D_i <= 1,000,000).$

    题目名称: cowjog

    输入格式:

    • 第$1$行: 3个数: $N,M,K$
    • 第$2..M+1$行: 第 $i+1 $行包含3个数 $X_i, Y_i,D_i$, 表示一条下坡的路.

    样例输入 (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)$ 

    【思路】

    Astar求k短路

    【code】

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define road 10000+10
    #define node 1000+10
    struct Edge
    {
        int x,y,z,next;
        Edge(int x=0,int y=0,int z=0,int next=0):
            x(x),y(y),z(z),next(next){}
    }edge[road];
    struct date
    {
        int x,g,h;
     bool operator < (const date &a) const
        {
            return g+h>a.g+a.h;
        }
    };
    int nl,m,k,x,y,z,sumedge,s,e,size;
    int head[node],ans[100+10],dis[node],cnt[node];
    bool vis[node];
    int add(int x,int y,int z)
    {
        edge[++sumedge]=Edge(x,y,z,head[x]);
        return head[x]=sumedge;
    }
    void spfa()
    {
        queue <int> q;
        memset(dis,127/3,sizeof(dis));
        dis[s]=0;vis[s]=1;q.push(s);    
        while(!q.empty())
        {
            int now=q.front();q.pop();
            vis[now]=0;
            for(int i=head[now];i;i=edge[i].next)
            {
                int to=edge[i].y;
                if(dis[to]>dis[now]+edge[i].z)
                {
                    dis[to]=dis[now]+edge[i].z;
                    if(!vis[to])
                    {
                        vis[to]=1;
                        q.push(to);
                    }
                }
            }
        }
    }
    void Astar()
    {
        priority_queue <date> qq;
        qq.push((date){e,0,dis[e]});
        while(!qq.empty())
        {
            date nn=qq.top();qq.pop();
            ++cnt[nn.x];
            if(cnt[nn.x]>k)continue;
            if(nn.x==s){
                ans[++size]=nn.g;
            }
            if(cnt[s]==k){
             return;
            }
            for(int i=head[nn.x];i;i=edge[i].next)
            {
                qq.push( (date){edge[i].y,nn.g+edge[i].z,dis[edge[i].y]});
            
            }
        }
        return;
    }
    int main()
    {
        freopen("cowjog.in ","r",stdin);
        freopen("cowjog.out","w",stdout);
        scanf("%d%d%d",&nl,&m,&k);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        s=1;e=nl;
        spfa();
        memset(ans,-1,sizeof(ans));
        Astar();
        for(int i=1;i<=k;i++)
        printf("%d
    ",ans[i]);
        return 0;
     } 

    【反思】

    spfa出队列时vis数组忘记清0......还有我忘记把第一个元素加入队列......

    还有我明明输出是对的硬生生的爆0....

  • 相关阅读:
    组件映射
    联合主键关联
    一对一单向双向主键关联
    7函数
    forEach与map
    3运算符与表达式
    作用域声明提升
    php程序设计 1,2章节
    angularJs(3)过滤器
    angularJs(1)指令篇
  • 原文地址:https://www.cnblogs.com/zzyh/p/6938602.html
Copyright © 2011-2022 走看看