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

最短路径

作者:互联网

最短路径
最短路径是指俩顶点之间经过的边上的权值之和和最少的路径。
Dijkstra算法
按路径长度递增的次序产生最短路径的算法。
比如有下面这样一个图,要求v0到v2的最短路径。
在这里插入图片描述
可以看到有两条路

  1. v0->v2=8
  2. v0->v1->v2=5
    所以最短路径就是5,dijkstra算法就是这样一个求解过程,来找到最短路径。
    题目
    大奶牛很热爱加班,他和朋友在凌晨一点吃完海底捞后又一个人回公司加班,为了多加班他希望可以找最短的距离回到公司。
    深圳市里有N个(2 <= N <= 1000)个公交站,编号分别为1…N。深圳是大城市,公交车整天跑跑跑。公交站1是大奶牛的位置,公司所在的位置是N。所有公交站中共有T (1 <= T <= 2000)条双向通道。大奶牛对自己的导航能力不太自信,所以一旦开始,他总是沿着一条路线走到底。
    大奶牛为了锻炼未来的ACMer,决定让你帮他计算他到公司的最短距离。可以保证存在这样的路存在。
    Input
    第一行:两个整数:T和N
    接下来T行:每一行都用三个空格分隔的整数描述一个轨迹。前两个整数是路线经过的公交站台。第三个整数是路径的长度,范围为1到100。
    Output
    一个整数,表示大奶牛回到公司的最小距离。
    Sample Input
    5 5
    1 2 20
    2 3 30
    3 4 20
    4 5 20
    1 5 100
    Sample Output
    90
    做这个题的首先需要构造一个邻接矩阵,然后再套dijkstra算法的模板就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int G[2010][2010];
int flag[2010];
int t,n;
int D[2010];
void Dij()
{
	D[1]=0;
	flag[1]=1;
	int i,j,k,w;
	for(i=1;i<=n;i++)
	{
		D[i]=G[1][i];
	}
	int mmin;
	for(i=1;i<=n;i++)
	{
		mmin=INF;
		for(j=1;j<=n;j++)
		{
			if(!flag[j]&&mmin>D[j])
			{
				k=j;
				mmin=D[k];
			}
		}
		flag[k]=1;
		for(w=1;w<=n;w++)
		{
			if(!flag[w]&&mmin+G[k][w]<D[w])
			{
				D[w]=mmin+G[k][w];
			}
		}
	}
}
int main()
{
	int a,b,c;
	while(cin>>t>>n)
	{
		memset(G,INF,sizeof(G));
		memset(flag,0,sizeof(flag));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i==j)
					G[i][i]=0;
		for(int i=0;i<t;i++)
		{
			cin>>a>>b>>c;
			if(c<G[a][b])
			{
				G[a][b]=G[b][a]=c;
			}
		}
		Dij();
		printf("%d\n",D[n]);
	}
	return(0);
} 

在这里插入图片描述

Floyd算法
这个算法我一开始没学习,因为学完dijkstra后就急着去做题目了,前天看了之后才发现这个算法太巧妙了,代码也十分简洁,但是有三个for,做题大部分都会导致时间超限。
题目:一个人的旅行
有时候无知也是一种错,伟大的fish学长从来不认识自己的家门在哪儿,有时候他甚至连自己的宿舍号都记不住,所以他很难找到一条从自己宿舍到各个教学楼的最短路,他知道自己宿舍楼距离教学楼有多远。而且他的宿舍楼有好多好多门,他得先去一个门作为起点,然后再出发去各个教学楼。
Input
输入数据有多组,每组第一行n,m,c分别表示一共有n条路,而且fish的宿舍楼门有m个,以及他要去的教学楼有c个。
接着n行有3个整数,a,b,time,表示a,b教学楼间需要走time分钟;1<=a<=1000&&1<=b<= 1000,教学楼门口十字路口很多。
接下来的n+ 1行有s个数,表示fish有s个楼门。
接着n+ 2行有c个数,表示fish想去c个教学楼。
Output
输出fish能去某个喜欢的教学楼的最短时间。
Sample Input
6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10
Sample Output
9
一看到这个题我就想到了Floyd,这就是为Floyd而出的题,但很不幸,时间超限。

//这是Floyd算法的Time Limit Exceeded代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int G[1010][1010];
int n,m,c;
int main()
{
	int a,b,time;
	int ansa[1010],ansb[1010];
	while(cin>>n>>m>>c)
	{
		memset(G,INF,sizeof(G));
		int N=-1;
		for(int i=0;i<n;i++)
		{
			cin>>a>>b>>time;
			N=max(N,a);
			N=max(N,b);
			if(G[a][b]>time)
			{
				G[a][b]=G[b][a]=time;
			}
		}
		int ans=INF;
		for(int i=0;i<m;i++)
		{
			cin>>ansa[i];
		}
		for(int i=0;i<c;i++)
		{
			cin>>ansb[i];
		}
		for(int i=0;i<=N;i++)
		for(int j=0;j<=N;j++)
		for(int k=0;k<=N;k++)
		{
			if(G[j][k]>G[j][i]+G[i][k])
			{
				G[j][k]=G[j][i]+G[i][k];
			}
		}
		for(int i=0;i<m;i++)
		{
			for(int j=0;j<c;j++)
			{
				ans=min(ans,G[ansa[i]][ansb[j]]);
			}
		}
		cout<<ans<<endl;
	}
} 

在这里插入图片描述

Josephu. 发布了18 篇原创文章 · 获赞 3 · 访问量 3602 私信 关注

标签:int,路径,最短,算法,time,教学楼,include
来源: https://blog.csdn.net/m0_46193982/article/details/104405671