牛慢跑

据说是\(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. 【Linux命令】Linux压缩及解压命令

    Linux压缩及解压命令 一.文件打包和压缩命令介绍 linux系统文件压缩格式,常用的有*.tar.gz.*.gz.*.zip.*.tar,还有*.rar..7z..bz2..tar.xz..tar ...

  2. 十二、深入理解Java内存模型

    深入理解Java内存模型 [1]CPU和缓存的一致性 ​ 我们应该都知道,计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又免不了要和数据打交道.而计算机上面的数据,是存放在主存当 ...

  3. ts缓存批量下载合并

    批量下载 curl -O https://cdn-host.media.yunxi.tv/recordM3u8/195820b37cec499da7a4b1b28269c7d0/tranbox/195 ...

  4. java的递归异常—一个异常可能由另一个异常触发

    关键字: Caused by nested exception java.lang.reflect.InvocationTargetException: null at sun.reflect.Nat ...

  5. SQL Server中使用SQL语句关闭数据库连接和删除数据库文件

    有时候我们想用DROP DATABASE语句删除数据库和数据库文件,会删不掉,因为有其他人正在使用要删除的数据库,这里有一个方法可以强制断开其它数据库连接,再删除数据库. 假如我们要删除的数据库是[T ...

  6. Microsoft.Practices.Unity

    // // Summary: // Register a type mapping with the container. // // Parameters: // container: // Con ...

  7. Asp.Net真分页技术

    最近学校要做课题,闲来没事研究了下Asp.net的分页,我使用Repeater进行数据的绑定,每次从数据库读取到8条数据填充到Repeater中,这样搞可以降低数据库的压力,提高效率. 效果图如下: ...

  8. JAVA性能监控与调优参考文档链接

    JAVA性能监控与调优参考文档链接 jdk8工具集 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.htmlTroub ...

  9. CMake编译的VS工程,安装时遇到错误:error MSB3073: 命令“setlocal

    错误提示 70>CMake Error at src/base/cmake_install.cmake:63 (file): 70> file INSTALL cannot find 70 ...

  10. global对象,数据存储方式和检测,包装器对象等

    1.理解global对象 global对象是作为 window 对象的一部分实现的,我们无法通过代码访问到 global 对象. 我们平时在全局环境下定义的内容(变量,函数,常量等等)都是作为 glo ...