迪杰斯特拉

求单源最短路径

迪杰斯特拉算法 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]);

}
posted @ 2020-04-09 16:05  arbor_one  阅读(123)  评论(0)    收藏  举报