练习题解(关于最短路径)

目录

1.租用游艇

2.邮递员送信

3.【模板】单源最短路径(标准版)


1.租用游艇

P1359 租用游艇 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

输入数据:

3
5 15
7

因为这道题数据不大,所有我们直接使用Floyd 算法。

这道题大家可能没看懂怎么存图,其实就是第x行的第y个元素,就是从x站到y站的租金,所以是一个半矩阵输入。

下面是完整AC代码:

#include<bits/stdc++.h>
#define inf 1234567890
using namespace std;
int a[201][201];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)a[i][j]=inf;//初始化 
	for(int i=1;i<n;i++)
		for(int j=i+1;j<=n;j++)
		{
			int x;
			cin>>x;
			a[i][j]=x;//邻边矩阵存图 
		}
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)//式子套用 
				a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
	cout<<a[1][n]<<endl;
	return 0;
}

2.邮递员送信

P1629 邮递员送信 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

输入数据:

5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2

这道题需要建立一个返回的图,因为这是有向图,所以1到其他节点和其他节点到1的最短路径不一定是相同的。

使用Dijkstra 算法,我们可以给dis的数组开成两倍大小,这样可以将反图也建在同一个图上,也可以重新建图,但是这样前面的方法方便一些。

下面是完整AC代码:

#include<bits/stdc++.h>
#define M 500010
#define inf 1234567890
using namespace std;
struct edge{
	int u,v,w,next;
}e[M];
struct node{
	int w,now;
	bool operator<(const node &k)const
	{
		return w>k.w;//堆优化,小的元素放在堆顶,大根堆 
	}
};
int head[M],re=0,n,m,s,v[M],dis[M];
priority_queue<node>q;
void add(int u,int v,int w)//链式前向星存图 
{
	e[++re].u=u;
	e[re].v=v;
	e[re].w=w;
	e[re].next=head[u];
	head[u]=re;
}
void dijkstra(int s)
{
	for(int i=1;i<=n*2;i++) dis[i]=inf;//将点设置为无穷大 
	dis[s]=0;//起点设置为0 
	node p;
	p.w=0,p.now=s;
	q.push(p);
	while(!q.empty()){
		node k=q.top();
		q.pop();
		int u=k.now;
		if(v[u]) continue;//如果遍历过,直接跳过循环 
		v[u]=1;
		for(int i=head[u];i;i=e[i].next){//下一个点 
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)//更新最小权重 
			{
				dis[v]=dis[u]+e[i].w;
				q.push((node){dis[v],v});
			}		
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int u,v,w;
		cin>>u>>v>>w;//建边 
		add(u,v,w);
		add(v+n,u+n,w);//建返回的图 
	}
	dijkstra(1);//求出1到其他点的最短路径 
	int ans=0;
	for(int i=1;i<=n;i++){
		ans+=dis[i];
	}
	dijkstra(1+n);//求出其他点到1的最短的路径 
	for(int i=1+n;i<=n*2;i++){
		ans+=dis[i];
	}
	cout<<ans<<endl;
	return 0;
}

3.【模板】单源最短路径(标准版)

P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

输入数据:

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

既然是模板题目,这里就直接出Dijkstra 算法来解决。

下面是AC完整代码:

#include<bits/stdc++.h>
#define M 500010
#define inf 1234567890
using namespace std;
struct edge{
	int u,v,w,next;
}e[M];
struct node{
	int w,now;
	bool operator<(const node &k)const
	{
		return w>k.w;//堆优化,小的元素放在堆顶,大根堆 
	}
};
int head[M],re=0,n,m,s,v[M],dis[M];
priority_queue<node>q;
void add(int u,int v,int w)//链式前向星存图 
{
	e[++re].u=u;
	e[re].v=v;
	e[re].w=w;
	e[re].next=head[u];
	head[u]=re;
}
void dijkstra()
{
	for(int i=1;i<=n;i++) dis[i]=inf;//将点设置为无穷大 
	dis[s]=0;//起点设置为0 
	node p;
	p.w=0,p.now=s;
	q.push(p);
	while(!q.empty()){
		node k=q.top();
		q.pop();
		int u=k.now;
		if(v[u]) continue;//如果遍历过,直接跳过循环 
		v[u]=1;
		for(int i=head[u];i;i=e[i].next){//下一个点 
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)//更新最小权重 
			{
				dis[v]=dis[u]+e[i].w;
				q.push((node){dis[v],v});
			}		
		}
	}
}
int main()
{
	cin>>n>>m>>s;
	for(int i=0;i<m;i++){
		int u,v,w;
		cin>>u>>v>>w;//建边 
		add(u,v,w);
	}
	dijkstra();
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
	return 0;
}
  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值