竞赛树优化Dijkstra效率非常高,如果不懂竞赛树,请看这里
附上代码
#include<cstdio> #define N (100000+10)*2 #define M 200000+10 using namespace std; int head[N],ednum=1,dis[N],book[N]; struct Edge{int next,to,d;}edge[M]; void add(int from,int to,int d){edge[++ednum]=(Edge){head[from],to,d};head[from]=ednum;} int n,m; struct heap{int val,who;}h[N]; heap min(heap a,heap b) { return (a.val<b.val)?a:b; } void update(int i) { if(i==1)return; h[i/2]=min(h[i],h[i^1]);update(i/2); return; } void Dijkstra() { for(int i=1;i<=2*n-1;i++){ dis[i]=h[i].val=1e9; h[i].who=i; } h[n].val=0; update(n); while(h[1].val!=1e9)//竞赛树非空 { int val=h[1].val; int who=h[1].who; int u=who-(n-1); dis[u]=val; //printf("%d %d ",u,dis[u]); h[who].val=1e9; update(who);//删除并调整 for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(dis[v]>dis[u]+edge[i].d) { dis[v]=dis[u]+edge[i].d; h[v+(n-1)].val=dis[u]+edge[i].d; update(v+(n-1));//修改并调整 } } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int u,v,d;scanf("%d%d%d",&u,&v,&d); add(u,v,d); } Dijkstra(); if(dis[n]==1e9){printf("-1");return 0;} printf("%d",dis[n]); return 0; }