链式前向星概念:https://blog.csdn.net/acdreamers/article/details/16902023/
模板:
1 int head[2*N],cnt; 2 3 struct Edge{ 4 int to,next,w; 5 }edge[N]; 6 7 void add(int u,int v,int w){ 8 edge[cnt].w=w;edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++; 9 edge[cnt].w=w;edge[cnt].to=u;edge[cnt].next=head[v];head[v]=cnt++; 10 } 11 12 void init(){ 13 cnt=0; 14 memset(head,-1,sizeof(head)); 15 } 16 17 //遍历:for(int i=head[u];~i;i=edge[i].next)
SPFA与优先队列优化的Dijkstra对比:
Dijkstra+heap是用小根堆(优先队列),每次取出d最小的点,来更新距离,那么这个点来说,最小距离就是当前的d。
SPFA是用队列,每次取出队头,来更新距离,它之后可能还会入队。它是一种动态逼近法,因为每次松弛距离都会减小,所以松弛一定会有结束的。
如果一个点入队超过n次就是存在负环。
模板Dijkstra:
1 vector < pair<int,int> > E[N]; 2 int n,m; 3 int d[N]; 4 bool vis[N]; 5 6 void init(){ 7 memset(vis,false,sizeof(vis)); 8 for(int i=0;i<N;i++) d[i]=INF; 9 for(int i=0;i<N;i++) E[i].clear(); 10 } 11 12 void dijkstra(int s,int d[]){ 13 priority_queue < pair<int,int> > Q; 14 d[s]=0; 15 Q.push(make_pair(-d[s],s)); 16 17 while(!Q.empty()){ 18 int now=Q.top().second; 19 Q.pop(); 20 if(vis[now]) continue; 21 vis[now]=true; 22 for(int i=0;i<E[now].size();i++){ 23 int v=E[now][i].first; 24 int D=d[now]+E[now][i].second; 25 if(d[v]>D){ 26 d[v]=D; 27 Q.push(make_pair(-d[v],v)); 28 } 29 } 30 } 31 }
模板SPFA:
1 void SPFA(int s){ 2 memset(vis,false,sizeof(vis)); 3 for(int i=0;i<N;i++) d[i]=INF; 4 d[s]=0; 5 queue <int> Q; 6 Q.push(s); 7 vis[s]=true; 8 while(!Q.empty()){ 9 int u=Q.front(); 10 Q.pop(); 11 vis[u]=false; 12 for(int i=head[u];~i;i=edge[i].next){ 13 int v=edge[i].to; 14 if(d[v]>d[u]+edge[i].w){ 15 d[v]=d[u]+edge[i].w; 16 if(!vis[v]){ 17 Q.push(v); 18 vis[v]=true; 19 } 20 } 21 } 22 } 23 }