zoukankan      html  css  js  c++  java
  • 【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是池塘.
      很快, BESSIE厌倦了一直走同一条路.所以她想走不同的路,更明确地讲,她想找出K条不同的路经.为了避免过度劳累,她想使这K条路经为最短的K条路经.
      请帮助BESSIE找出这K条最短路经的长度.
      你的程序需要读入农场的地图,一些从X_i到Y_i 的路经和它们的长度(X_i, Y_i, D_i).

    Input

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

    Output

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

    Sample Input

      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

    Sample Output

      1
      2
      2
      3
      6
      7
      -1

    HINT

      1 <= M <= 10,000, 1 <= N <= 1000, 1 <= K <= 100

     

    Main idea

      给定一张图,输出1~k短路的距离。

    Solution

      既然是求k短路,那我们使用A*搜索,先反向建图,记录终点到每一个点的最短路,然后把这个dist当做估价来跑A*即可。可以证明:第k次搜到的路即是k短路

    Code

      1 #include<iostream>  
      2 #include<string>  
      3 #include<algorithm>  
      4 #include<cstdio>  
      5 #include<cstring>  
      6 #include<cstdlib>  
      7 #include<cmath>
      8 #include<queue>
      9 using namespace std;
     10 typedef long long s64;
     11  
     12 const int ONE = 2e6+5;
     13  
     14 int n,m,k;
     15 int S,T;
     16 int dist[ONE],vis[ONE],Output[ONE],tou,wei;
     17 int next[ONE],first[ONE],go[ONE],w[ONE],tot;
     18 int Ans[ONE],num;
     19  
     20 struct point
     21 {
     22         int x,y,z;
     23 }a[ONE];
     24  
     25 struct power
     26 {
     27         int x,real,eva;
     28         bool operator <(const power &a) const
     29         {
     30             return a.real + a.eva < real + eva;
     31         }
     32 };
     33  
     34 inline int get()
     35 {
     36         int res=1,Q=1;  char c;
     37         while( (c=getchar())<48 || c>57)
     38         if(c=='-')Q=-1;
     39         if(Q) res=c-48; 
     40         while((c=getchar())>=48 && c<=57) 
     41         res=res*10+c-48;
     42         return res*Q; 
     43 }
     44  
     45 void Add(int u,int v,int z)
     46 {
     47         next[++tot]=first[u];   first[u]=tot;   go[tot]=v;  w[tot]=z;
     48 }
     49  
     50 void SPFA(int x)
     51 {
     52         int q[10000001];
     53         memset(dist,63,sizeof(dist));
     54         tou = 0; wei = 1;
     55         vis[x] = 1; dist[x] = 0; q[1] = x;
     56         while(tou < wei)
     57         {
     58             int u = q[++tou];
     59             for(int e=first[u];e;e=next[e])
     60             {
     61                 int v = go[e];
     62                 if(dist[v] > dist[u] + w[e])
     63                 {
     64                     dist[v] = dist[u] + w[e];
     65                     if(!vis[v]) vis[v] = 1, q[++wei] = v;
     66                 }
     67             }
     68             vis[u] = 0;
     69         }
     70 }
     71  
     72 void Astar()
     73 {
     74         priority_queue <power> q;
     75         q.push( (power){S, 0, dist[S]} );
     76         while(!q.empty())
     77         {
     78             power u = q.top();  q.pop();
     79             if(u.x == T) Ans[++num] = u.real;
     80             if(++Output[u.x] > k) continue;
     81             if(Output[T] == k) return;
     82             for(int e=first[u.x]; e; e=next[e])
     83             {
     84                 int v=go[e];
     85                 q.push( (power){v, u.real+w[e], dist[v]} );
     86             }
     87         }
     88 }
     89  
     90 int main()
     91 {
     92         n=get();    m=get();    k=get();
     93         S=n,    T=1;
     94         for(int i=1;i<=m;i++)
     95         {
     96             a[i].x=get();   a[i].y=get();   a[i].z=get();
     97             Add(a[i].y, a[i].x, a[i].z);
     98         }
     99         SPFA(T);
    100          
    101         memset(first,0,sizeof(first));  tot=0;
    102         for(int i=1;i<=m;i++) Add(a[i].x,a[i].y,a[i].z);
    103          
    104         Astar();
    105          
    106         for(int i=1;i<=k;i++)
    107             printf("%d
    ",Ans[i]!=0?Ans[i]:-1);
    108          
    109 }
    View Code
  • 相关阅读:
    在注册表中添加windows鼠标右键菜单
    关于MVC中无法将类型为“System.Int32”的对象强制转换为类型“System.String”的问题。
    dns
    ntp
    研究比对搞定博客 canvas-nest.js
    linux 添加ssh和开启ssh服务apt管理的ubuntu
    xshll 连接ubuntu出现 ssh服务器拒绝了密码
    yum和rpm
    服务器无法远程连接原因分析
    关于服务器卡顿的几个原因
  • 原文地址:https://www.cnblogs.com/BearChild/p/6847100.html
Copyright © 2011-2022 走看看