zoukankan      html  css  js  c++  java
  • BZOJ1598: [Usaco2008 Mar]牛跑步

    n<=1000而m<=10000的DAG中求从n到1的前K<=100短路,不存在输出-1。

    方法一:之前写过“第二短路”,比较2次;如果是要“前K短路”的话,dis需要是一个支持查找、插入(找到一个新的第u大,u<=K,需要插入u)、删除(插入后把最后一个删除)的东西,那就Treap或者Splay乱写一通啦。代码如下:

    如下个头。编程复杂度不说,一定要用SPFA实现,正确性不明,时间复杂度也难说。

    方法二:查了题解。根据数据规模和图的特点选择A*:数据n和K都较小,可以感觉,从起点n到其它点的路程中,第v,v>=K+1短路是没有意义的;图没有环。

    所以A*中,估价函数h=当前状态的运动路程+从这个点到终点的最短路。为了得到后者,需把所有的边反过来找1到每个点的最短路。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<queue>
      6 //#include<iostream>
      7 using namespace std;
      8 
      9 int n,m,K;
     10 #define maxn 1011
     11 #define maxm 10011
     12 struct Edge{int to,v,next;};
     13 const int inf=0x7fffffff;
     14 struct Graph
     15 {
     16     Edge edge[maxm*2];int le;
     17     int first[maxn],dis[maxn],vis[maxn];
     18     struct Node
     19     {
     20         int x,v;
     21         bool operator < (const Node &b) const {return v<b.v;}
     22         bool operator > (const Node &b) const {return v>b.v;}
     23     };
     24     priority_queue<Node,vector<Node>,greater<Node> > q;
     25     Graph()
     26     {
     27         memset(first,0,sizeof(first));
     28         le=2;
     29     }
     30     void insert(int x,int y,int v)
     31     {
     32         Edge &e=edge[le];
     33         e.to=y;e.v=v;
     34         e.next=first[x];
     35         first[x]=le++;
     36     }
     37     void Dijkstra()
     38     {
     39         for (int i=1;i<=n;i++) dis[i]=inf;
     40         memset(vis,0,sizeof(vis));
     41         dis[1]=0;
     42         q.push((Node){1,0});
     43         while (!q.empty())
     44         {
     45             const int now=q.top().x,d=q.top().v;
     46             q.pop();
     47             if (vis[now]) continue;
     48             vis[now]=1;
     49             for (int i=first[now];i;i=edge[i].next)
     50                 if (dis[edge[i].to]>d+edge[i].v)
     51                 {
     52                     dis[edge[i].to]=d+edge[i].v;
     53                     q.push((Node){edge[i].to,dis[edge[i].to]});
     54                 }
     55         }
     56     }
     57 }reG,G;
     58 struct heapnode
     59 {
     60     int x,f,g;
     61     bool operator < (const heapnode &b) const
     62     {return f+g<b.f+b.g;}
     63     bool operator > (const heapnode &b) const
     64     {return f+g>b.f+b.g;}
     65 };
     66 priority_queue<heapnode,vector<heapnode>,greater<heapnode> > que;
     67 int ans[maxn],cnt[maxn];
     68 void Astar()
     69 {
     70     que.push((heapnode){n,0,reG.dis[n]});
     71     cnt[n]=1;
     72     while (!que.empty())
     73     {
     74         const int x=que.top().x,d=que.top().f;
     75         que.pop();
     76         if (cnt[x]==K) continue;
     77         cnt[x]++;
     78         if (x==1)
     79         {
     80             ans[cnt[x]]=d;
     81             if (cnt[x]==K) break;
     82         }
     83         for (int i=G.first[x];i;i=G.edge[i].next)
     84             que.push((heapnode){G.edge[i].to,G.edge[i].v+d,reG.dis[G.edge[i].to]});
     85     }
     86 }
     87 int x,y,v;
     88 int main()
     89 {
     90     scanf("%d%d%d",&n,&m,&K);
     91     for (int i=1;i<=m;i++)
     92     {
     93         scanf("%d%d%d",&x,&y,&v);
     94         G.insert(x,y,v);
     95         reG.insert(y,x,v);
     96     }
     97     reG.Dijkstra();
     98     memset(ans,-1,sizeof(ans));
     99     Astar();
    100     for (int i=1;i<=K;i++) printf("%d
    ",ans[i]);
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    Linux编译安装boost
    apue源码make:/usr/include/bits/timex.h:31:7: 错误:expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ be的解决方法
    POI导出word表格
    centos设置tomat开机自启
    算法题
    Oracle获取当前数据库的所有表名字段名和注释
    ajax提交文件
    Activemq Java
    Oracel 获取表数据大小
    Corn获取下一次执行时间
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7240748.html
Copyright © 2011-2022 走看看