ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

最短路径

2020-02-20 10:41:19  阅读:369  来源: 互联网

标签:int 路径 最短 算法 time 教学楼 include


最短路径
最短路径是指俩顶点之间经过的边上的权值之和和最少的路径。
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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有