【Luogu】P2901牛慢跑(K短路模板)
2024-08-28 00:20:24
K短路居然用A*……奇妙。
先建反图从终点(1)跑一遍最短路,再A*,用堆存当前点到终点距离+从起点到当前点距离。
每次取出终点都可以视为发现了一个新的最短路。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#define maxn 1020
#define maxm 10020
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Node{
int pnt,dis;
bool operator <(const Node a)const{
return dis<a.dis;
}
bool operator ==(const Node a)const{
return dis==a.dis;
}
bool operator <=(const Node a)const{
return dis<=a.dis;
}
}; struct Heap{
Node heap[maxn*];
int size;
Heap(){size=;}
inline void push(Node x){
heap[++size]=x;
register int i=size,k;
while(i>){
k=i>>;
if(heap[k]<=heap[i]) return;
swap(heap[k],heap[i]);
i=k;
}
}
inline Node pop(){
Node ans=heap[]; heap[]=heap[size--];
register int i=,k;
while((i<<)<=size){
k=i<<;
if(k<size&&heap[k|]<heap[k]) k|=;
if(heap[i]<=heap[k]) return ans;
swap(heap[k],heap[i]);
i=k;
}
return ans;
}
}s; int ans[maxn],cnt;
int dis[maxn];
bool vis[maxn]; struct Picture{
struct Edge{
int next,to,val;
}edge[maxm*];
int head[maxn],num;
Picture(){memset(vis,,sizeof(vis));num=;memset(head,,sizeof(head));}
inline void add(int from,int to,int val){
edge[++num]=(Edge){head[from],to,val};
head[from]=num;
}
void prepare(int Start){
memset(dis,/,sizeof(dis)); dis[Start]=;
queue<int>q; q.push(Start);
while(!q.empty()){
int from=q.front();q.pop();
vis[from]=;
for(int i=head[from];i;i=edge[i].next){
int to=edge[i].to;
if(dis[to]<=dis[from]+edge[i].val) continue;
dis[to]=dis[from]+edge[i].val;
if(vis[to]) continue;
vis[to]=; q.push(to);
}
}
return;
}
void Astar(int Start,int tme){
s.push((Node){Start,dis[Start]});
while(s.size){
Node from=s.pop();
int x=from.pnt,dst=from.dis;
if(x==) ans[++cnt]=dst;
if(tme==cnt) return;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
s.push((Node){to,dst-dis[x]+edge[i].val+dis[to]});
}
}
}
}Pre,Sub; int main(){
memset(ans,-,sizeof(ans));
int n=read(),m=read(),e=read();
for(int i=;i<=m;++i){
int x=read(),y=read(),z=read();
if(x<y) swap(x,y);
Pre.add(x,y,z);
Sub.add(y,x,z);
}
Sub.prepare();
Pre.Astar(n,e);
for(int i=;i<=e;++i) printf("%d\n",ans[i]);
return ;
}
最新文章
- 使用Jmeter监测服务器cpu、内存等性能
- Sqlserver 导出数据脚本
- CSS 禁止浏览器滚动条的方法(转)
- 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
- git SSH keys
- GTP V0 和 GTP V1
- LightOj 1024 - Eid (求n个数的最小公约数+高精度)
- java中的log中的用法和小结
- 利用Php ssh2扩展实现svn自动提交到测试服务器
- Spark处理Json格式数据(Python)
- Mysql开启远程
- [Framework Design Guideline]
- Spring源码情操陶冶-AOP之Advice通知类解析与使用
- HTML学习笔记 css定位浮动及瀑布流案例 第十三节 (原创) 参考使用表
- 微信小程序 画布drawImage实现图片截取
- SDN 软件定义网络----学习1
- AVH IP网络广播系统
- Hibernate表关系03
- redis 配置详解
- vim 开启我们的Python之旅