牛慢跑

据说是\(k\)短路模板,要用\(A^*\),然而我不会。我是用拓扑排序加堆优化广搜水过去的。第一道完全靠自己做出来的紫题,调了两个小时,交了两遍。果然我还是太菜了。

正解的话,可以看红太阳的博客

题面

给出\(n\)个点\(m\)条边的有向无环图,求从\(n\)到\(1\)的前\(k\)条最短路的值。

\(1≤N≤1000 ,1 <= M <= 10000 ,1≤K≤100\)

输入格式

第\(1\)行:三个以空格分隔的整数:\(N,M\)和\(K\).

第\(2..M + 1\)行:第\(i + 1\)行描述了使用三个以空格分隔的整数的下坡牛路径:\(X_i,Y_i\)和$D_i(1≤Di≤1000000) $

输出格式

行\(1..K\):行\(i\)包含第\(i\)个最短路径的长度,如果不存在这样的路径,则为\(-1\)。如果多次出现最短路径长度,请务必在输出中多次列出。

输入样例

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
2
2
3
6
7
-1

拓扑排序加堆优化广搜

以下是我的神奇做法。

要找前\(k\)条最短路,怎么找?我观察了一下样例的图,发现每个点的路径长度会被更新很多次,但都是由直接指向他的点更新来的(废话),也就是说,他前面的点怎样更新的我不关心,我只关心这个点前\(k\)条最短路的长度。

那直接用堆存一下就好了。

但是我们要保证他前面的点已经更新完了。前面说了这是一个有向无环图,自然想到拓扑排序。

但我之前犯了一个错误,它花费了我一个多小时的时间。这个题要求必须从\(n\)号点出发,但是有些点\(n\)号点到不了,它们一开始入度就为零。如果不把这些点的影响去掉,后面就会出错。果然我菜鸡的本质难以掩盖。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
long long read(){
long long x=0;int f=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return f?-x:x;
} int n,m,k;
struct Dier{//前向星
int to,next,w;
}a[10004];
int head[1001],cnt;
void add(int x,int y,int z){//单向边
a[++cnt].to=y,a[cnt].next=head[x],a[cnt].w=z,head[x]=cnt;
} priority_queue<int,vector<int>,greater<int> >q[1005];//小根堆
int in[1001],Q[1001],h,t;
// 入度 队列 int main(){
n=read(),m=read(),k=read();
for(int i=1,x,y,z;i<=m;++i){
x=read(),y=read(),z=read();
add(x,y,z),in[y]++;
} //拓扑
for(int i=n;i;--i)
if(!in[i]) Q[++t]=i;
for(int i=1;i<=t;++i){
if(Q[i]==n) continue;//n号点的影响不应该去掉
int u=Q[i];
for(int i=head[u],v;v=a[i].to,i;i=a[i].next){
in[v]--;
if(!in[v]) Q[++t]=v;//斩草不除根,后面麻烦无穷
//只要不是从n号点直接或间接转移过来的入度都要去掉,因为他们会妨碍我们后面的入队
}
} t=1,Q[1]=n;//初始化一下
q[n].push(0);
while(h<t){//广搜
int u=Q[++h],ls=0;
while(u!=1&&!q[u].empty()&&++ls<=k){//只取前k条就好
//保证1号点的距离不会被pop掉
for(int i=head[u],v;v=a[i].to,i;i=a[i].next)
q[v].push(q[u].top()+a[i].w);//更新距离
q[u].pop();
}
//计算入度一定要独立出来,不能和更新距离放在一起,因为那样会导致入度被减很多次
for(int i=head[u],v;v=a[i].to,i;i=a[i].next){
in[v]--;
if(!in[v]) Q[++t]=v;
}
}
while(!q[1].empty()&&k){//输出答案
printf("%d\n",q[1].top()),q[1].pop(),k--;
}
for(int i=1;i<=k;++i) printf("-1\n");//有可能并没有k条路可以走
return 0;
}

欢迎指正评论O(∩_∩)O~~

【K短路】牛慢跑的更多相关文章

  1. 【Luogu】P2901牛慢跑(K短路模板)

    题目链接 K短路居然用A*……奇妙. 先建反图从终点(1)跑一遍最短路,再A*,用堆存当前点到终点距离+从起点到当前点距离. 每次取出终点都可以视为发现了一个新的最短路. #include<cs ...

  2. Bzoj 1598: [Usaco2008 Mar]牛跑步 dijkstra,堆,K短路,A*

    1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 427  Solved: 246[Submit][St ...

  3. bzoj 1598: [Usaco2008 Mar]牛跑步 [k短路 A*] [学习笔记]

    1598: [Usaco2008 Mar]牛跑步 题意:k短路 ~~貌似A*的题目除了x数码就是k短路~~ \[ f(x) = g(x) + h(x) \] \(g(x)\)为到达当前状态实际代价,\ ...

  4. K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院

    A*属于搜索的一种,启发式搜索,即:每次搜索时加一个估价函数 这个算法可以用来解决K短路问题,常用的估价函数是:已经走过的距离+期望上最短的距离 通常和Dijkstra一起解决K短路 BZOJ1598 ...

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

    1598: [Usaco2008 Mar]牛跑步 Time Limit: 10 Sec  Memory Limit: 162 MB Description BESSIE准备用从牛棚跑到池塘的方法来锻炼 ...

  6. bzoj 1598: [Usaco2008 Mar]牛跑步【A*K短路】

    A*K短路模板,详见https://blog.csdn.net/z_mendez/article/details/47057461 算法流程: 把有向图全建成反向边,跑一遍所有点到t的最短路记为dis ...

  7. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  8. POJ 2449Remmarguts' Date K短路模板 SPFA+A*

    K短路模板,A*+SPFA求K短路.A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点 ...

  9. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

随机推荐

  1. FFmpeg 常用API

    一.通用API 1.1 av_register_all() 初始化 libavformat 和注册所有的复用器.解复用器和协议处理器.如果不调用这个函数,可以调用下面的三个函数来选择支持的格式. 注册 ...

  2. 1+X证书Web前端开发规范手册

    一.规范目的 1.1 概述 为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档. 本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本 ...

  3. 安装docker后修改docker文件目录

    docker会下载容器,运行会挂载磁盘,所以我们需要把docker装在大容量的分区. 安装 https://docs.docker.com/install/linux/docker-ce/centos ...

  4. 第二十二节:Asp.Net Core中使用托管服务实现后台任务

    1. 说明 BackgroundService 是用于实现长时间运行的 IHostedService 的基类,使用程序集:Microsoft.Extensions.Hosting. 2. 实现方式 继 ...

  5. A Pattern Language for Parallel Programming

    The pattern language is organized into four design spaces.  Generally one starts at the top in the F ...

  6. springboot 使用 freemarker 无法正常跳转的问题?

    1.springboot 使用 freemarker 无法正常跳转的问题? 参考:https://blog.csdn.net/Lin_xiaofeng/article/details/79122053 ...

  7. jdbc:mysql:/// jdbc连接数据url简写方式

    正常情况下我们写jdbc连接本地mysql数据库的时候通常是这样写 jdbc:mysql:localhost:3306/数据库名 下面就是要提到的简单的方法 jdbc:mysql:///数据库名

  8. Elasticsearch PUT 插入数据

    { "error": { "root_cause": [ { "type": "illegal_argument_exceptio ...

  9. MySQL5.7增量备份恢复全实战

    一. 简介 1. 增量备份 增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加或者被修改的文件.这就意味着,第一次增量 备份的对象是进行全备后所产生的增加和修改的文件; ...

  10. java--set,Collections,map

    set 特点: 无序, 不允许重复 没有索引 Set<String> set = new HashSet<String>(); set.add("hello" ...