众所周知,SPFA死了

 

一种神奇的Dijkstra,用node.min_dis!=dis[top]判断是否入队,实测比正常的Dijkstra快得多

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

inline int rd(){
  int ret=0,f=1;char c;
  while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
  while(isdigit(c))ret=ret*10+c-'0',c=getchar();
  return ret*f;
}

const int MAXN=3000000;
const int M=6000000;

struct Edge{
  int next,to,w;
}e[M<<1];
int ecnt,head[MAXN];
inline void adds(int x,int y,int w){
  e[++ecnt].next = head[x];
  e[ecnt].to = y;
  e[ecnt].w = w;
  head[x] = ecnt;
}

struct Node{
  int id,w;
  Node(int x=0,int y=0){id=x;w=y;}
  bool operator < (const Node &rhs) const {
    return w>rhs.w;
  }
}top;
priority_queue<Node> Q;
int dis[MAXN],vis[MAXN];
void dij(int s){
  memset(dis,0x3f,sizeof(dis));
  Q.push(Node(s,0));dis[s]=0;
  while(!Q.empty()){
    top=Q.top();Q.pop();
    int mnid=top.id,mn=top.w;
    if(vis[mnid]) continue;
    if(mn!=dis[mnid])continue;vis[mnid]=1;
    for(int i=head[mnid];i;i=e[i].next){
      int v=e[i].to;
      if(dis[v]>dis[mnid]+e[i].w){
        dis[v]=dis[mnid]+e[i].w;
        Q.push(Node(v,dis[v]));
      }
    }
  }
}

int n,m,s;

int main(){
    cin>>n>>m>>s;
    for(int i=1;i<=m;i++){
        int x,y,w;
        x=rd();y=rd();w=rd();
        adds(x,y,w);
    }
    dij(s);
    for(int i=1;i<=n;i++){
        printf("%d ",dis[i]);
    }
    return 0;
}
很快的Dijkstra

相关文章: