最短路学习

为了天梯赛 

系统性的学习最短路,主要是为了手敲出来。

最朴素的dijkstra就是n^2的,

1.初始化d数组无穷大,

2.每次找到距离起点最小且没有访问过的点,

3.然后用这个点对每个点进行遍历,如果起点最直接到某个点的距离d[i]< 起点经过这个点的距离d[x]+a[x][y],就更新

4.重复2,3直到每个点都访问过。

复杂度O(n^2)

#include<bits/stdc++.h>
using namespace std;
const int M = 100000+100;
const int N = 10000+100;
int cnt=0;
int head[M];
int d[M];
bool v[M];
int a[N][N];
int n,m;
struct node
{
	int to,next,val;
}edge[M];
void add(int x,int y,int w)
{
	edge[++cnt].to=y;
	edge[cnt].val=w;
	edge[cnt].next=head[x];
	head[x]=cnt;
}
void dijkstra()
{
	memset(d,0x3f,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=1;y<=n;y++)
			d[y]=min(d[y],d[x]+a[x][y]);
	}
}
int main()
{
	int u,v,w;
	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++)
	{
		scanf("%d%d%d",&u,&v,&w);
		a[u][v]=min(a[u][v],w);
	}
	dijkstra();
	for(int i=1;i<=n;i++)
	{
		cout<<d[i]<<endl;
	}
	
	return 0;
}
/*
input:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
output:
0 1 8 4 13 17

*/

用链式前向星写。

#include<bits/stdc++.h>
using namespace std;
const int M = 100000+100;
const int N = 10000+100;
int head[M];
int d[M];
bool v[M];
int n,m,cnt;
struct node
{
	int to,next,val;
}edge[M];
void add(int x,int y,int w)
{
	edge[++cnt].to=y;
	edge[cnt].val=w;
	edge[cnt].next=head[x];
	head[x]=cnt;
}
void dijkstra()
{
	memset(d,0x3f,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 j=head[x];j;j=edge[j].next)
		{
			int v=edge[j].to;
			int val=edge[j].val;
			d[v]=min(d[v],d[x]+val);
		}	
	}
}
int main()
{

	int u,v,w;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
	}
	dijkstra();
	for(int i=1;i<=n;i++)
	{
		cout<<d[i]<<endl;
	}
	return 0;
}
/*
input:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
output:
0 1 8 4 13 17

*/

优先队列优化dij,复杂度O(mlog(n))

#include<bits/stdc++.h>
using namespace std;
const int M = 100000+100;
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > >q;
int n,m,cnt;
int d[M];
int head[M];
bool v[M];
struct EDGE
{
	int to,next,val;
}edge[M];
void add(int x,int y,int w)
{
	edge[++cnt].to=y;
	edge[cnt].val=w;
	edge[cnt].next=head[x];
	head[x]=cnt;
}
void dijkstra(int origin)
{
	memset(d,0x3f,sizeof(d));
	memset(v,0,sizeof(v));
	d[origin]=0;
	q.push(make_pair(0,1));
	while(q.size())
	{
		int x=q.top().second;q.pop();
		if(v[x])continue;
		v[x]=1;
		for(int i=head[x];i;i=edge[i].next)
		{
			int w=edge[i].val;
			int v=edge[i].to;
			if(d[v] > d[x] + w)
			{
				d[v] = d[x] + w;
				q.push(make_pair(d[v],v));
			}
		}
	}
}
int main()
{
	int u,v,w;
	cin>>n>>m;
	for(int i = 1; i<= m; i++)
	{
		scanf("%d %d %d",&u,&v,&w);
		add(u,v,w);
	}
	dijkstra(1);
	for(int i = 1; i <= n; i++)
	{
		cout<<d[i]<<endl;
	}
	return 0;
}
 

猜你喜欢

转载自blog.csdn.net/bjfu170203101/article/details/88795007