求最短路 (dijikstra + Floyd) 模板

本文详细介绍并对比了三种经典的图算法:未优化的Dijkstra算法、优先队列优化的Dijkstra算法及Floyd算法。通过具体代码实现展示了如何解决图中的最短路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.未优化的dijikstra算法(O(n^2))

 

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1100 , INF = 0x3f3f3f3f;
int graph[N][N],dis[N],vis[N];
int n,m;
void dijkstra(int s)
{
	int MIN = INF;
	int next;
	memset(vis,0,sizeof(vis));
	for(int i = 1 ; i <= n ; i++)
		dis[i] = graph[s][i];
	dis[s] = 0;
	vis[s] = 1;
	for(int i = 1 ; i <= n ; i++)
	{
		MIN = INF;
		for(int j = 1 ; j <= n ; j++)			
			if(!vis[j] && MIN > dis[j])
			{
				MIN = dis[j];
				next = j;
			}
		vis[next] = 1;
		for(int j = 1 ; j <= n ; j++)
			if(!vis[j] && dis[j] > dis[next] + graph[next][j] )
				dis[j] = dis[next] + graph[next][j];
	}
}
int main()
{
	int from,to,cost;
	while(cin>>n>>m)	 					//n为点数,m为边数;
	{
		for(int i = 1 ; i <= n ; i++)
			for(int j = 1 ; j <= n ; j++)
				graph[i][j] = INF;
		for(int i = 1 ; i <= n ; i++)
			graph[i][i] = 0;
		for(int i = 0 ; i < m ; i++)
		{
			cin>>from>>to>>cost;
			if(graph[from][to] > cost)		//当有重边时,优先选取权值小的边;
				graph[from][to] = graph[to][from] = cost;
		}
		dijkstra(1);						//以点1为起点,求以起点到其他各个点的最短路径;
		cout<<dis[n]<<endl;					//输出点1到点n的最短路径长度
	}
	return 0;
}

2.优先队列优化的dijikstra算法(O(mlogn))

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N = 1100 , INF = 0x3f3f3f3f;
int vis[N],dis[N],graph[N][N];
int n,m;
struct Edge
{
	int to,cost;
	Edge(int _to = 0,int _cost = 0):to(_to),cost(_cost)
	{}
	bool operator < (const Edge & A) const
	{
		return cost > A.cost;
	}
};
vector <Edge> vec[N];
void dijikstra(int s)
{
	memset(vis,0,sizeof(vis));
	for(int i = 1 ; i <= n ; i++)
		dis[i] = INF;
	dis[s] = 0;
	priority_queue <Edge> pq;
	while(!pq.empty())	pq.pop();
	pq.push(Edge(s,0));
	Edge t;
	while(!pq.empty())
	{
		t = pq.top();
		pq.pop();
		int u = t.to;
		if(vis[u])	continue;
		vis[u] = 1;
		int len = vec[u].size();
		for(int i = 0 ; i < len ; i++)
        {
            int v = vec[u][i].to;
            int cost=vec[u][i].cost;
            if(!vis[v] && dis[v] > dis[u]+cost)
            {
                dis[v] = dis[u]+cost;
                pq.push(Edge(v,dis[v]));
            }
        }
	}
}
int main()
{
	int from,to,cost;
	while(cin>>n>>m)
	{
		for(int i = 1 ; i <= n ; i++)
			for(int j = 1 ; j <= n ; j++)
				graph[i][j] = (i == j ? 0 : INF); 
		for(int i = 0 ; i < m ; i++)
		{
			cin>>from>>to>>cost;
			if(graph[from][to] > cost)
			{
				graph[from][to] = graph[to][from] = cost;	
				vec[from].push_back(Edge(to,cost));
				vec[to].push_back(Edge(from,cost));
			}
		}
		dijikstra(1);
		cout<<dis[n]<<endl;
	}
	return 0;
}

3.Floyd

#include <iostream>
#include <cmath>
using namespace std;
const int N = 1100, INF = 0x3f3f3f3f;
int graph[N][N];
int main()
{
	int n;
	while(cin>>n)
	{
		for(int i = 1 ; i <= n ; i++)
			for(int j = i + 1 ; j <=n ; j++)
			{
				cin>>graph[i][j];
				graph[j][i] = graph[i][j];
			}
		for(int i =1 ;i <= n ; i++)
			graph[i][i] = 0;
		for(int k = 1 ; k <= n ; k++)
			for(int i = 1 ; i <= n ; i++)
				for(int j = 1 ; j <=n ; j++)
					graph[i][j] = min(graph[i][j],graph[i][k] + graph[k][j]);
		cout<<graph[1][n]<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值