SPFA:
适用于存在负边权的情况
思想是遍历每个点,松弛它的出边
时间复杂度O(nm)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6,inf=INT_MAX;
int head[maxn],dis[maxn],cnt,n,m,s;
bool vis[maxn];
struct Edge
{
int next,to,w;
}edge[maxn];
void add(int u,int v,int w)
{
edge[++cnt].next=head[u];
edge[cnt].w=w;
edge[cnt].to=v;
head[u]=cnt;
}
queue<int> q;
void spfa(int s)
{
for(int i=1;i<=n;++i)
dis[i]=inf;
int u,v;
q.push(s);
dis[s]=0;
vis[s]=true;
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i;i=edge[i].next)
{
v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=0;i<m;++i)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
spfa(s);
for(int i=1;i<=n;++i)
cout<<dis[i]<<' ';
cout<<endl;
return 0;
}
DIJKSTRA:
适用于不存在负边权的情况
思想是贪心,每次从最短距离中选取一个点加入最短距离已确定点集
时间复杂度O(mlogn)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6,inf=INT_MAX;
int head[maxn],dis[maxn],cnt,n,m,s;
bool vis[maxn];
struct Edge
{
int next,to,w;
}edge[maxn];
struct node
{
int pos,d;
bool operator <(const node& x) const
{
return x.d<d;
}
};
void add(int u,int v,int w)
{
edge[++cnt].next=head[u];
edge[cnt].w=w;
edge[cnt].to=v;
head[u]=cnt;
}
void dijkstra(int s)
{
for(int i=1;i<=n;++i)
dis[i]=inf;
priority_queue<node> q;
dis[s]=0;
q.push(node{s,0});
while(!q.empty())
{
node now=q.top();
q.pop();
int u=now.pos;
if(vis[u]) continue;
vis[u]=true;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
if(!vis[v])
{
q.push(node{v,dis[v]});
}
}
}
}
}
int main()
{
cin>>n>>m>>s;
for(int i=0;i<m;++i)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
dijkstra(s);
for(int i=1;i<=n;++i)
cout<<dis[i]<<' ';
cout<<endl;
return 0;
}