【模板】最短路径-Dijkstra

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40727946/article/details/86515915

两种写法

第一种:时间复杂度:O(n2)点的数量,未使用优先队列优化

 /*
时间复杂度:O(n2)点的数量
*/

#include<bits/stdc++.h>
using namespace std;
#define MAX 10000 
#define inf 2147483647
//0x3f3f3f3f

long long int d[MAX];//结点i的路径长度为d[i]
long long int v[MAX];//标记是否使用过该点
long long int w[MAX][MAX];//记录两点之间的花费 
long long int start=0,n,m;//起始点begin 点n表示点的数量 m表示边的数量
long long int fa[MAX];//维护父亲结点,用来找路径 
void init()//初始化
{
	for(int i=1;i<=n;i++)//把起点之外的点的距离设为inf,起点的距离设为0 
	{
		d[i]=(i==start ? 0:inf);
	}	
	memset(v,0,sizeof(v));//全部为未使用    0:未使用  1:使用
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			w[i][j]=inf;
}
void Dijkstra()
{
	for(int i=1;i<=n;i++)
	{
		int pos,Min=inf;
		for(int j=1;j<=n;j++)//未标记的结点中,结点d[j]值最小的点 pos  
		{
			if(!v[j]&&d[j]<=Min)
			{
				Min=d[j];
				pos=j;
			}
		}
		v[pos]=1;//标记最小结点 pos
		for(int j=1;j<=n;j++)//对于从pos出发的所有边(pos,j),更新 d[j]=min(d[j],d[pos]+w[pos][j])
		{
			//d[j]=min(d[j],d[pos]+w[pos][j]);
			if(d[j]>d[pos]+w[pos][j])
			{
				d[j]=d[pos]+w[pos][j];
				fa[j]=pos;
			} 
			
		}
	}
	
}
void findway(int k)
{
	long long int value=d[k];
	int z=k;
	while(value!=0)
	{
		for(int i=1;i<=n;i++)
		{
			if(d[z]==d[i]+w[i][z])
			{
				value-=w[i][z];
				z=i;
				cout<<z<<endl;
				break;
			}
		}
	}
	
}

int main()
{
	cin>>n>>m>>start;
	init();
	for(int i=0;i<m;i++)
	{
		long long int a,b,c;
		cin>>a>>b>>c;
		//无向图 
		if(w[a][b]>c)
			w[a][b]=c;
		//w[b][a]=c;
	}
	
	Dijkstra();
	for(int i=1;i<=n;i++)
	{
		if(i==1)
			printf("%lld",d[i]);
		else
			printf(" %lld",d[i]);
	}
	cout<<endl;
	//findway(5);
	for(int i=1; i<=n; i++)
	{
		if(i!=start)
		{
			cout<<i;
	        int p=i;
	        while(fa[p]!=0)
			{
	            cout<<"-->"<<fa[p];
	            p=fa[p];
	        }
	        cout<<endl;
		}
    }
	return 0;
} 

/*
输入:
5 7 1
1 2 10
1 4 25
1 5 80
2 3 40
3 5 10
4 3 20
4 5 50
输出:
0 10 45 25 55
2-->1
3-->4-->1
4-->1
5-->3-->4-->1
*/

第二种:时间复杂度:O(mlogn)点的数量,使用优先队列优化

 /*
时间复杂度:O(mlogn)点的数量
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005 		//最大值为结点的个数 
#define INF 2147483647
typedef long long int ll;

vector<ll> G[maxn];	//当点的数量过大时,这里有可能会内存溢出,开全局变量就行 

struct Dijkstra 
{
	struct Edge 
	{
		ll from, to, dist;
		Edge(int u, int v, int d) :from(u), to(v), dist(d) {}
	};
	ll n, m,k;			//n个点,m个边 
	vector<Edge> edges;	 
	bool done[maxn]; 	//是否已永久标号
	ll d[maxn]; 		//s到各个点的距离
	ll p[maxn]; 		//最短路中的上一条弧
	void init(ll n) 	//初始化边和点 
	{
		this->n = n;
		for (int i = 0; i < n; i++) G[i].clear(),p[i]=0;
		edges.clear();
	}
	void AddEdge(ll from, ll to, ll dist) //添加边 
	{
		edges.push_back(Edge(from, to, dist));
		k = edges.size();
		G[from].push_back(k - 1);
	}
	struct HeapNode 	//寻找未使用的最小d[i],把的d[i]和i绑定到一起 
	{
		ll d, u;
		bool operator < (const HeapNode& rhs) const 
		{
			return d > rhs.d;
		}
	};
	void dijkstra(int s) 
	{
		priority_queue<HeapNode> Q;
		for (int i = 0; i < n; i++) d[i] = INF;
		d[s] = 0;
		memset(done, 0, sizeof(done));
		Q.push((HeapNode) { 0, s });
		while (!Q.empty()) 
		{
			HeapNode x = Q.top(); Q.pop();
			ll u = x.u;
			if (done[u]) continue;
			done[u] = true;
			ll glen= G[u].size();
			for (int i = 0; i < glen; i++) 
			{
				Edge& e = edges[G[u][i]];
				if (d[e.to] > d[u] + e.dist) 
				{
					d[e.to] = d[u] + e.dist;
					p[e.to] = u;
					Q.push((HeapNode) { d[e.to], e.to });
				}
			}
		}
	}
};
int main()
{
	Dijkstra a;
	ll n,m,start;
	cin>>n>>m>>start;
	a.n=n+1;		//模板从0到n-1,如果需要从1到n,则需要加 1 
	a.m=m;
	a.init(a.n);
	for(int i=0;i<a.m;i++)
	{
		ll from,to,dist;
		cin>>from>>to>>dist;
		a.AddEdge(from,to,dist);
	}
	a.dijkstra(start);
	for(int i=1;i<a.n;i++)
	{
		if(i==1)
			 cout<<a.d[i];
		else
			cout<<' '<<a.d[i];
	}
	cout<<endl;
	for(int i=1; i<a.n; i++)
	{
		if(i!=start)
		{
			cout<<i;
	        ll d=i;
	        while(a.p[d]!=0)
			{
	            cout<<"-->"<<a.p[d];
	            d=a.p[d];
	        }
	        cout<<endl;
		}
    }
	return 0;
}

/*
洛谷 P3371
洛谷 P4779

输入:
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出:
0 2 4 3
2-->1
3-->2-->1
4-->2-->1
*/ 

猜你喜欢

转载自blog.csdn.net/qq_40727946/article/details/86515915