最短路问题

最短路问题

最短路是图论里一个非常经典的问题。

单源最短路

我们这里使用比较出名的 Dijkstra 算法,时间复杂度 O(n2)

Dijkstra 朴素写法

算法步骤:

  • 将距离数组设为 Inf,这里使用 0x3F3F3F3F
  • 将初始点设为 0
  • 找到一个没有标记过且距离最短的点。
  • 如果没有找到,则跳出函数。
  • 标记该点,对该点的连边做松弛操作。
  • 重复执行 Step 25

Code1

#include <iostream>
using namespace std;
#define MAXN 10005
#define MAXM 500005 
#define Inf 2147483647
int h[MAXN],tot,n,m;
int dis[MAXN];
bool vis[MAXN];
struct CFS
{
	int to;
	int nxt;
	int wei;
	CFS(){};
	CFS(int t,int n,int w){
		nxt=n;
		to=t;
		wei=w;
	};
}edge[MAXM*2];
void addedge(int u,int v,int w)
{
	tot++;
	edge[tot]=CFS(v,h[u],w);
	h[u]=tot;
	return ;
}
void Dijkstra(int st)
{
	for(int i=1;i<=n;i++) dis[i]=Inf;
	dis[st]=0;
	for(int i=1;i<=n;i++)
	{
		int min_d=Inf;
		int v=0;
		for(int j=1;j<=n;j++)
		{
			if(!vis[j]&&dis[j]<min_d)
			{
				min_d=dis[j];
				v=j;
			}
		}
		if(min_d==Inf) break;
		vis[v]=true;
		for(int j=h[v];j;j=edge[j].nxt) dis[edge[j].to]=min(dis[edge[j].to],dis[v]+edge[j].wei);
	}
}
int main()
{
	int st;
	cin>>n>>m>>st;
	for(int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		addedge(u,v,w);
	}
	Dijkstra(st);
	for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	return 0;
}

Dijkstra 堆优化

主要将 3643 Line 进行优化,时复是 O(nlogn+m)

Code2

#include <iostream>
#include <queue>
using namespace std;
#define MAXN 1005
#define MAXM 100005 
#define Inf 0x3f3f3f3f
int h[MAXN],tot,n,m;
int dis[MAXN];
bool vis[MAXN];
struct CFS
{
	int to;
	int nxt;
	int wei;
	CFS(){};
	CFS(int t,int n,int w){
		nxt=n;
		to=t;
		wei=w;
	};
}edge[MAXN];
void addedge(int u,int v,int w)
{
	tot++;
	edge[tot]=CFS(v,h[u],w);
	h[u]=tot;
	return ;
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > qu;
void Dijkstra(int st)
{
	qu.push(make_pair(0,st));
	while(qu.size())
	{
		int min_d=qu.top().first;
		int v=qu.top().second;
		qu.pop();
		if(min_d!=dis[v]) continue;
		for(int j=h[v];j;j=edge[j].nxt)
		{
			if(dis[edge[j].to]>dis[v]+edge[j].wei)
			{
				dis[edge[j].to]=dis[v]+edge[j].wei;
				qu.push(make_pair(dis[edge[j].to],edge[j].to));
			}
		}
	}
}
int main()
{
	int st;
	cin>>n>>m>>st;
	for(int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		addedge(u,v,w);
		addedge(v,u,w);
	}
	Dijkstra(st);
	for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
	return 0;
}

多源最短路

比较好于理解与编写的是 Floyd 算法。

Floyd

算法步骤:

  • 本算法使用类似 DP 的写法。

Code3

#include <iostream>
#include <iomanip>
#include <string.h>
using namespace std;
int n,m;
int g[105][105];
void addedge(int u,int v,int w)
{
	g[u][v]=w;
	return ;
}
void Floyd()
{
	for(int k=1;k<=n;k++)
		for(int i=0;i<=n;i++)
			for(int j=0;j<=n;j++)
				g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
	return ;
}
int main()
{
	memset(g,0x3f,sizeof g);
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		addedge(u,v,w);
		addedge(v,u,w);
	}
	Floyd();
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(i==j) cout<<setw(12)<<"0";
			else cout<<setw(12)<<g[i][j];
		}
		cout<<endl;
	}
	return 0;
}
# input
6 5
1 2 3
2 6 8
6 5 1
2 3 5
3 6 1
# output
0           3           8           1061109567  10          9
3           0           5           1061109567  7           6
8           5           0           1061109567  2           1
1061109567  1061109567  1061109567  0           1061109567  1061109567
10          7           2           1061109567  0           1
9           6           1           1061109567  1           0
posted @   RainCQwQ  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示