单源最短路径模板
单源最短路径模板
Dijkstra:
时间复杂度:\(O((n+m)\log n)\)
#include<bits/stdc++.h>
using namespace std;
using pii=pair<long long,int>;
const int N=1e5+10;
int n,m,s,hd[N],ver[2*N],nxt[2*N],w[2*N],tot;
long long dis[N];
bool vis[N];
void add(int u,int v,int c){//有向边
ver[++tot]=v;w[tot]=c;nxt[tot]=hd[u];hd[u]=tot;
}
void dij(int s){
memset(dis,0x3f,sizeof(dis));//初始化
priority_queue<pii,vector<pii>,greater<pii> > q;
dis[s]=0;
q.push({0,s});
while(q.size()){
int u=q.top().second;q.pop();//记得弹出
if(vis[u]) continue;//已经确定最短距离的节点不再处理
vis[u]=true;//标记为已确定
for(int i=hd[u];i;i=nxt[i]){//遍历u的所有出边
int v=ver[i];
if(dis[v]>dis[u]+w[i]){//松弛操作
dis[v]=dis[u]+w[i];
q.push({dis[v],v});//新的可能距离入堆
}
}
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m>>s;
for(int i=1,u,v,c;i<=m;i++){
cin>>u>>v>>c;
add(u,v,c);
}
dij(s);
for(int i=1;i<=n;i++){
cout<<dis[i]<<' ';
}
return 0;
}
SPFA:
时间复杂度:\(O(nm)\)
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,s,hd[N],ver[2*N],nxt[2*N],w[2*N],tot;
long long dis[N];
bool vis[N];
void add(int u,int v,int c){//有向边
ver[++tot]=v;w[tot]=c;nxt[tot]=hd[u];hd[u]=tot;
}
void SPFA(int s){
for(int i=1;i<=n;i++) dis[i]=(1ll<<31)-1;//初始化(注意题目要求)
queue<int> q;
dis[s]=0;
q.push(s);
while(q.size()){
int u=q.front();q.pop();//记得弹出
vis[u]=false;//出队后解除标记(允许多次入队)
for(int i=hd[u];i;i=nxt[i]){//遍历u的所有出边
int v=ver[i];
if(dis[v]>dis[u]+w[i]){//松弛操作
dis[v]=dis[u]+w[i];
if(!vis[v]){//如果v不在队列中,则入队
q.push(v);
vis[v]=true;
}
}
}
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>m>>s;
for(int i=1,u,v,c;i<=m;i++){
cin>>u>>v>>c;
add(u,v,c);
}
SPFA(s);
for(int i=1;i<=n;i++){
cout<<dis[i]<<' ';
}
return 0;
}

浙公网安备 33010602011771号