最短路径
作者:互联网
最短路径
最短路径是指俩顶点之间经过的边上的权值之和和最少的路径。
Dijkstra算法
按路径长度递增的次序产生最短路径的算法。
比如有下面这样一个图,要求v0到v2的最短路径。
可以看到有两条路
- v0->v2=8
- 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