迪杰斯特拉
求单源最短路径
迪杰斯特拉算法 O(n*n)
#inlcude<iostream>
#include<algorithm>
#Include<stdio.h>
#include<cstring>
using namespace std;
int a[1000][1000],d[1000],n,m;
bool v[1000];
void dijkstra()
{
memset(d,0f3f,sizeof(d));
memset(v,0,sizeof(v));
d[1]=0;
for(int i=1;i<n;i++)
{
int x=0;
for(int j=1;j<=n;j++)
if(!v[j]&&(x==0||d[j]<d[x]))
x=j;
v[x]=1;
for(int y=;y<=n;y++)
d[y]=min(d[y],d[x]+a[x][y]);
}
}
int main()
{ cin>>n>>m;
memset(a,0x3f,sizeof(a));
for(int i=1;i<=n;i++)a[i][i]=0;
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
a[x][y]=z;
}
dijkstra();
for(int i=1;i<=n;i++)
printf("%d ",d[i]);
}
优化后 O((m+n)logn)
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int N=100100,M=100100;
int head[N],Next[N],d[M],ver[M],edge[N],tot,n,m;
int p;//这个是起点
bool v[N];
priority_queue<pair<int,int> >q;//用大根堆维护,pair的first存的是dist的相反数,second存的是节点编号,以这种方法找到最小值。
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
void dijkstra(int p){
memset(d,0x3f,sizeof(d));
memset(v,0,sizeof(v));
d[p]=0;
q.push(make_pair(0,p));
while(q.size())
{
int x=q.top.second; q.pop();
if(v[x])continue;
v[x]=1;
for(int i=head[x];i;i=Next[i])
{
int y=vet[i],z=edge[i];
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));
}
}
}
}
int main()
{
cin>>n>>m>>p;
for(int i =1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
}
dijkstra(p);
for(int i=1;i<=n;i++)
printf("%d ",d[i]);
}
浙公网安备 33010602011771号