最短路径问题【Dijkstra】

题目链接传送门
D e s c r i p t i o n Description Description

平面上有n个点(N<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点直线的距离。现在的任务是找出从一点到另一点之间的最短路径。

I n p u t Input Input

输入文件short.in,共有n+m+3行,其中:
第一行为一个整数n。
第2行到第n+1行(共n行),每行的两个整数x和y,描述一个点的坐标(以一个空格隔开)。
第n+2行为一个整数m,表示图中的连线个数。
此后的m行,每行描述一条连线,由两个整数I,j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点。

O u t p u t Output Output

输出文件short.out仅一行,一个实数(保留两位小数),表示从S到T的最短路径的长度。

S a m p l e   I n p u t Sample~Input Sample Input

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

S a m p l e   O u t p u t Sample~Output Sample Output

3.41


最短路Dijkstra
在我的这篇博客里说过
我们要学习4种最短路算法,
今天,我们就来看看第二种最短路算法

——Dijkstra

Dijkstra用来计算从一个点到其他所有点的最短路径的算法,是一种单源最短路径算法。也就是说,只能计算起点只有一个的情况。
Dijkstra的时间复杂度是 O ( N 2 ) O (N2) O(N2),它不能处理存在负边权的情况。

让我们用图+文字的方式来解释一下。


算法开始时,作为起点的 d i s [ 1 ] = 0 dis[1] = 0 dis[1]=0,其他的点 d i s [ i ] = 0 x 7 f f f f f f f dis[i] = 0x7fffffff dis[i]=0x7fffffff
最短路径问题【Dijkstra】_第1张图片
这时 d i s [ 3 ] dis[3] dis[3] d i s [ 5 ] dis[5] dis[5]被它们的最后一个中转点2修改为了最短路径。
最短路径问题【Dijkstra】_第2张图片这时 d i s [ 4 ] dis[4] dis[4]也被它的最后一个中转点3修改为了最短路径。
蓝白点思想

具体实现:

#include
#include
#include
using namespace std;
int n,m,x,y,s,e,k,a[110][3];
int minn,maxx;
double f[101][101];
double c[101];
bool b[101];
int main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
	   cin>>a[i][1]>>a[i][2];
    memset(f,100,sizeof(f));
    cin>>m;
    for(int i=1; i<=m; i++)
     {
     	cin>>x>>y;                                     //预处理x.y间距离f[x][y]
     	f[x][y]=f[y][x]=sqrt(double((a[x][1]-a[y][1])*(a[x][1]-a[y][1]))+double((a[x][2]-a[y][2])*(a[x][2]-a[y][2])));
     }
    cin>>s>>e;
    for(int i=1; i<=n; i++)
       c[i]=f[s][i];
    memset(b,0,sizeof(b));                            //dijkstra 最短路
    b[s]=1;
    c[s]=0;
    for(int i=1; i<=n-1; i++)
     {
     	minn=10000000;
     	k=0;
     	for(int j=1; j<=n; j++)
     	 if(b[j]==0&&c[j]<minn)
     	  {
     	  	minn=c[j];
     	  	k=j;
     	  }
     	if(k==0) break;
     	b[k]=1;
        for(int j=1; j<=n; j++)
         if(c[k]+f[k][j]<c[j]&&b[j]==0)
           c[j]=c[k]+f[k][j];
     }
    printf("%.2lf",c[e]); 
	return 0;
}

你可能感兴趣的:(题解(较高质量),图论)