题目描述
平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。
输入
第1行:1个整数n
第2..n+1行:每行2个整数x和y,描述了一个点的坐标
第n+2行:1个整数m,表示图中连线的数量
接下来有m行,每行2个整数i和j,表示第i个点和第j个点之间有连线
最后1行:2个整数s和t,分别表示源点和目标点
输出
第1行:1个浮点数,表示从s到t的最短路径长度,保留2位小数
样例输入
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
看标题就知道,我们要用floyd和dijkstra算法解决之~
插播一段介绍。
floyd就是可以找图中任意两点的最短路径~一个一个去中转~简单粗暴很好想也很好写~可以处理负边权~然而时间复杂度...O(N³)。
没事这道题数据比较小还是好过~~~
dijkstra就是一种单源最短路径算法~同样是去中转~时间复杂度O(N²)..不能处理负边权就很抓狂了。
还好这道题不会有负边权~~~
具体介绍还是去找别人吧因为我不想多描述..
再然后其中会用到两点间的距离公式~
(学过勾股定理的一般都能推出来)
第一次提交,各对了一个测试点..
检查了很久,发现一个最根本的问题..
我当时是这样输入的..
for(i=1;i<=n;i++)
{
scanf("%d%d",&p,&q);
ds[p][q]=ds[q][p]=sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));
}
没错!!<=n!!不该是<=m吗?!!
亏我还对着floyd的核心代码看了好久
所以floyd的问题算是解决了:
#include
#include
int x[105],y[105],n,m,s,t;
double ds[105][105];
int main()
{
freopen("floyd.in","r",stdin);
freopen("floyd.out","w",stdout);
int i,j,k,p,q;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
ds[i][j]=4000000010.0;
if(i==j) ds[i][j]=0.0;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
ds[p][q]=ds[q][p]=sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));
}
scanf("%d%d",&s,&t);
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(ds[i][k]+ds[j][k]
然后就是对着dijkstra一阵死磕的日子..
在若干个小时的艰苦奋斗之后!!
终于!!
AC!!
#include
#include
int x[105],y[105],n,m,s,t,v[105];
double ds[105][105],c[105];
int main()
{
freopen("dijkstra.in","r",stdin);
freopen("dijkstra.out","w",stdout);
int i,j,p,q;
double g;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
ds[i][j]=4000000000.0;
if(i==j) ds[i][j]=0.0;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&p,&q);
ds[p][q]=ds[q][p]=sqrt((x[p]-x[q])*(x[p]-x[q])+(y[p]-y[q])*(y[p]-y[q]));
}
scanf("%d%d",&s,&t);
for(i=1;i<=n;i++)
c[i]=4000000000.0;
c[s]=0.0;
v[s]=1;
for(i=1;i<=n;i++)
c[i]=ds[i][s];
for(i=1;i
其实..两种代码..各有各的用途吧..........
然后我好像也没什么要说了..
没错我就是懒得删freopen