最短路径问题
题目描述
平面上有 n 个点(n<=100),每个点的坐标均在-10000~10000 之间。其中的一些点之间有连线 。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离 。现在的任务是找出从一点到另一点之间的最短路径 。
输入
输入共 n+m+3 行,其中:
第一行为整数 n。
第 2 行到第 n+1 行 (共 n 行 ),每行两个整数 x 和 y,描述了一个点的坐标。
第 n+2 行为一个整数 m,表示图中连线 的个数。
此后的 m 行(m<=1000),每行描述一条连线,由两个整数 i和 j 组成,表示第 i个点和第 j 个点之
间有连线 。
最后一行 :两个整数 s 和 t,分别表示源点和目标点。
输出
输出仅一行,一个实数(保留两位小数),表示从 s 到 t 的最短路径长度 。
样例输入
5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5
样例输出
3.41
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; float work(int x1,int x2,int y1,int y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int n,m,s,t; float x[101]={0},y[101]={0},w[101][101],dis[101]={0}; bool pd[101][101],used[101]={0}; int main() { memset(w,0,sizeof(w)); memset(pd,0,sizeof(pd)); memset(dis,127,sizeof(dis)); cin>>n; for(int i=1;i<=n;i++) {cin>>x[i]>>y[i];} cin>>m; for(int i=1;i<=m;i++) { int a,b; cin>>a>>b; w[b][a]=w[a][b]=work(x[a],x[b],y[a],y[b]); pd[a][b]=pd[b][a]=1; } cin>>s>>t; dis[s]=0; for(int i=1;i<=n;i++) { int mini=0; for(int j=1;j<=n;j++) if(!used[j]&&dis[j]<dis[mini])mini=j; if(mini==0)break; used[mini]=1; for(int j=1;j<=n;j++) if(pd[mini][j]&&dis[mini]+w[mini][j]<dis[j]) dis[j]=dis[mini]+w[mini][j]; } printf("%.2f",dis[t]); return 0; } |
Subscribe