题目链接

  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 ;
}

最新文章

  1. 使用Jmeter监测服务器cpu、内存等性能
  2. Sqlserver 导出数据脚本
  3. CSS 禁止浏览器滚动条的方法(转)
  4. 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
  5. git SSH keys
  6. GTP V0 和 GTP V1
  7. LightOj 1024 - Eid (求n个数的最小公约数+高精度)
  8. java中的log中的用法和小结
  9. 利用Php ssh2扩展实现svn自动提交到测试服务器
  10. Spark处理Json格式数据(Python)
  11. Mysql开启远程
  12. [Framework Design Guideline]
  13. Spring源码情操陶冶-AOP之Advice通知类解析与使用
  14. HTML学习笔记 css定位浮动及瀑布流案例 第十三节 (原创) 参考使用表
  15. 微信小程序 画布drawImage实现图片截取
  16. SDN 软件定义网络----学习1
  17. AVH IP网络广播系统
  18. Hibernate表关系03
  19. redis 配置详解
  20. vim 开启我们的Python之旅

热门文章

  1. C#使用API屏蔽系统热键和任务管理器
  2. 成都Uber优步司机奖励政策(2月26日)
  3. 天津Uber优步司机奖励政策(12月21日到12月27日)
  4. 4946: [Noi2017]蔬菜
  5. YARN 与Maprd 配置
  6. 了解和分析iOS Crash
  7. MySQL日期比较
  8. RF上传图片各种失败坑,使用pywin32来操作windows窗体
  9. mysql新手进阶03
  10. 【WXS】变量定义保留标识符