路径问题
全源最短路
Floyd
void floyd(){
for(int i=0;i<maxn;Dis[i][i]=0,i++) for(int j=0;j<maxn;j++) Dis[i][j]=inf;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) Dis[i][j]=min(Dis[i][j],Dis[i][k]+Dis[k][j]);
}
模板题
Johnson
重载运算符
bool operator < (Node const x ,Node const y){
return x.dis>y.dis;
}
核心代码
bool spfa(int s){
for(int i=0;i<=n;i++) H[i]=inf,Cnt[i]=Vis[i]=0;
Q.push(s); Vis[s]=1; H[s]=0;
while(!Q.empty()){
int u=Q.front(); Q.pop(); Vis[u]=0;
for(int i=Pre[u];i;i=E[i].next){
int v=E[i].to,w=E[i].w;
if(H[v]>H[u]+w){
H[v]=H[u]+w;
Cnt[v]=Cnt[u]+1;
if(Cnt[v]>n) return 1;
if(!Vis[v]) Vis[v]=1,Q.push(v);
}
}
}
return 0;
}
void dijkstra(int s){
for(int i=1;i<=n;i++) Dis[i]=inf,Vis[i]=0;
Pq.push((Node){s,0}); Dis[s]=0;
while(!Pq.empty()){
int u=Pq.top().id; Pq.pop();
if(Vis[u]) continue;
Vis[u]=1;
for(int i=Pre[u];i;i=E[i].next){
int v=E[i].to,w=E[i].w;
if(Dis[v]>Dis[u]+w){
Dis[v]=Dis[u]+w;
Pq.push((Node){v,Dis[v]});
}
}
}
}
void johnson(){
spfa(0);
for(int i=1;i<=n;i++) dijkstra(i);
}
模板题
单源最短路
Dijkstra
重载运算符
bool operator < (Node const x ,Node const y){
return x.dis>y.dis;
}
堆优化 + vector + 最短路计数
void dijkstra(){
int curr;
Dis[1]=0;
Cnt[1]=1;
Pq.push((Edge){1,0
});
while(!Pq.empty()){
curr=Pq.top().id;
Pq.pop();
if(Vis[curr]) continue;
Vis[curr]=1;
for(int i=0;i<V[curr].size();i++){
if(Dis[curr]+V[curr][i].w<Dis[V[curr][i].id]){
Dis[V[curr][i].id]=Dis[curr]+V[curr][i].w;
Cnt[V[curr][i].id]=Cnt[curr];
Pq.push((Edge){V[curr][i].id,Dis[V[curr][i].id]
});
}
else if(Dis[curr]+V[curr][i].w==Dis[V[curr][i].id]){
Cnt[V[curr][i].id]+=Cnt[curr];
}
}
}
}
模板题
堆优化 + 链式前向星
void dijkstra(int s){
for(int i=1;i<=n;i++) Dis[i]=inf,Vis[i]=0;
Pq.push((Node){s,0}); Dis[s]=0;
while(Pq.size()){
int u=Pq.top().id; Pq.pop();
if(Vis[u]) continue;
Vis[u]=1;
for(int i=Pre[u];i;i=E[i].next){
int v=E[i].to,w=E[i].w;
if(Dis[v]>Dis[u]+w){
Dis[v]=Dis[u]+w;
Pq.push((Node){v,Dis[v]});
}
}
}
}
模板题
SPFA
链式前向星 + 判负环
PS: 若求最长路,则为判正环
bool spfa(int s){
for(int i=0;i<maxn;i++) Dis[i]=inf,Vis[i]=Cnt[i]=0;
Q.push(s); Vis[s]=1; Dis[s]=0;
while(!Q.empty()){
int u=Q.front(); Q.pop(); Vis[u]=0;
for(int i=Pre[u];i;i=E[i].next){
int v=E[i].to,w=E[i].w;
if(Dis[v]>Dis[u]+w){
Dis[v]=Dis[u]+w;
Cnt[v]=Cnt[u]+1;
if(Cnt[u]>=n) return 0;
if(!Vis[v]) Q.push(v),Vis[v]=1;
}
}
}
return 1;
}
模板题
单源次短路(严格)
Dijkstra
void dijkstra(){
for(int i=1;i<=n;i++) Dis[i]=Dis2[i]=inf;
Pq.push((Node){1,0}); Dis[1]=0;
while(Pq.size()){
int u=Pq.top().id; Pq.pop();
for(int i=Pre[u];i;i=E[i].next){
int v=E[i].to,w=E[i].w;
if(Dis[v]>Dis[u]+w){
Dis2[v]=Dis[v];
Dis[v]=Dis[u]+w;
Pq.push((Node){v,Dis[v]});
}
else if(Dis2[v]>Dis[u]+w&&Dis[v]!=Dis[u]+w){
Dis2[v]=Dis[u]+w;
Pq.push((Node){v,Dis[v]});
}
if(Dis2[v]>Dis2[u]+w) Dis2[v]=Dis2[u]+w;
}
}
}