其他分享
首页 > 其他分享> > 廉价最短路径

廉价最短路径

作者:互联网

廉价最短路径

题目

图是由一组顶点和一组边组成的。一条边连接两个顶点。例如,图1表示了一个有4个顶点V、5条边的图。图中,每条边e是有方向的,方向从起点到终点,并且每条边都有价值。用整数0,1,…,m-1可以表示一个有m个顶点的图。
在这里插入图片描述
一条路径连接了一个点Vi和另一个点Vj,其方向与经过的一系列边的方向一致。路径的长度是途经边的条数,路径的费用是边价值的总和。对于一个给定的图,你的任务是在所有最短路径中,找出需要最少费用的连接V0和V1的路径。一个需要最少费用的最短路径称之为廉价最短路径。

让我们重新考虑图1,从0到1的最短路径是只含一条边的路径0→1,费用是10。当然,还有更便宜的路:0→2→1和 0→3→1,但是它们比第一条路径长(有2条边)。所以,0→1是廉价最短路径。

看一下另一个例子,图2,它有2条最短路径,其长度是2,路径0→3→1(费用=4)比路径0→2→1(费用=5)花费少。还用另一条路径0→2→3→1(费用=3),虽然便宜但是很长。所以,廉价最短路径是0→3→1。

输入

输入文件第一行有两个整数m和n,用一个空格隔开,其中,m是顶点数,而n是边数。接下来的n行给出所有的边及其价值,每行有3个整数(相邻两个整数间有一个空格),表示起点,终点和边的价值。顶点最多有100个,编号在0到99之间。边最多有1000条,其价值在0到215-1之间。

输出

输出文件仅有一行包含一个整数,即V0→V1的廉价最短路径的费用。当出现有多个廉价最短路径的情况时,它们的费用是一样的。

输入样例

4 5
0 2 2
0 3 2
0 1 10
2 1 2
3 1 2

输出样例

10

思路

这道题就是一道最短路,我这里用floyed来做。
读入的时候先标记长度,然后floyed的时候判断要变一下,最后输出点0到点1的最小费用,就可以了。

代码

#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[101][101],b[101][101],x,y;
int main()
{
	scanf("%d%d",&n,&m);//读入
	memset(a,127/3,sizeof(a));//初始化
	memset(b,127/3,sizeof(b));//初始化
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);//读入
		scanf("%d",&a[x][y]);//读入
		b[x][y]=1;//标记长度为1
	}
	for (int k=0;k<n;k++)//floyed
	for (int i=0;i<n;i++)
	for (int j=0;j<n;j++)
	if (i!=j&&j!=k&&i!=k)
	if ((b[i][k]+b[k][j]<b[i][j])||(b[i][k]+b[k][j]==b[i][j]&&a[i][k]+a[k][j]<a[i][j]))//判断是否更优
	{
		b[i][j]=b[i][k]+b[k][j];//加长度
		a[i][j]=a[i][k]+a[k][j];//加费用
	}
	printf("%d",a[0][1]);//输出
	return 0;
}

标签:费用,路径,廉价,最短,顶点,101
来源: https://blog.csdn.net/weixin_43346722/article/details/91879181