最短路-Dijkstra算法
不能处理负权边
未优化:时间复杂度为O(n^2) ,n为顶点数
堆优化:时间复杂度大概为O((m+n)logm),m为边数
模板题(未优化):P3371 【模板】单源最短路径(弱化版)
模板题(堆优化):P4779 【模板】单源最短路径(标准版)
Code 未优化:
#include<iostream>
#include<vector>
using namespace std;
struct node{
int v;
int w;
};
const int INF=0x7fffffff;
const int MAX_N=1e4+5;
int n,m;
vector<node> e[MAX_N];
int dist[MAX_N];
bool tag[MAX_N];
void Dijkstra(int S)
{
for(int i=1;i<=n;++i)
dist[i]=INF;
for(auto c:e[S])
dist[c.v]=min(dist[c.v],c.w);
dist[S]=0; tag[S]=true;
int u,Min;
for(int i=1;i<n;++i)
{
Min=INF;
for(int j=1;j<=n;++j)
if(tag[j]==false&&dist[j]<Min){
Min=dist[j]; u=j;
}
tag[u]=true;
for(auto c:e[u])
if(tag[c.v]==false&&dist[c.v]>dist[u]+c.w){
dist[c.v]=dist[u]+c.w;
}
}
}
int main()
{
int u,v,w,S;
scanf("%d%d%d",&n,&m,&S);
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&u,&v,&w);
e[u].push_back(node{v,w});
}
Dijkstra(S);
for(int i=1;i<n;++i)
printf("%d ",dist[i]);
printf("%d\n",dist[n]);
return 0;
}
Code 堆优化:
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int,int> pr;
const int MAX_N=1e5+5;
const int INF=1e9+5;
int n,m;
vector<pr> e[MAX_N];
int dist[MAX_N];
bool tag[MAX_N];
priority_queue<pr,vector<pr>,greater<pr>> Q;
void Dijkstra(int S){
for(int i=1;i<=n;++i)
dist[i]=INF;
dist[S]=0;
Q.push({0,S});
int u,v,w;
while(!Q.empty()){
u=Q.top().second; Q.pop();
if(tag[u]) continue;
tag[u]=true;
for(int j=0;j<e[u].size();++j)
{
v=e[u][j].first; w=e[u][j].second;
if(!tag[v]&&dist[v]>dist[u]+w){
dist[v]=dist[u]+w;
Q.push({dist[v],v});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int u,v,w,S;
cin>>n>>m>>S;
for(int i=0;i<m;++i)
{
cin>>u>>v>>w;
e[u].push_back({v,w});
}
Dijkstra(S);
for(int i=1;i<n;++i)
cout<<dist[i]<<" ";
cout<<dist[n]<<endl;
return 0;
}