wikioi 2602 最短路径问题 Dijkstar

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

第一行为整数n。

第2行到第n+1行(共n行),每行两个整数x和y,描述了一个点的坐标。

    第n+2行为一个整数m,表示图中连线的个数。

    此后的m行,每行描述一条连线,由两个整数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

直接套用Dijkstar模板就行,唯一需要改动的就是路径问题,只需求两左边点之间距离即可。

与nyoj 115 城市平乱 基本一样

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 105
#define inf 100000000.1
double  map[maxn][maxn];
double low[maxn];
int N,M;
struct node{
    double x,y;
}a[maxn];

double Dijk(int v0,int v1)
{
    int i , j ,pos,k;
    double min;
    int vis[1001];
    memset(vis,0,sizeof(vis));
    for(i = 1 ; i <= N ; i++  )
    {
         low[i] = map[v0][i];
//         printf("%lf ",low[i]);
    }
//    puts("");
    low[v0] = 0;
    vis[v0] = 1;
    for(i = 1; i < N ; i++)
    {
        min  = inf ;
        for(j = 1; j <= N ; j++)
        {
            if(!vis[j] && min > low[j])
            {
                min = low[j];
                pos = j ;
            }
        }
//        printf("!!%lf\n",min);
        vis[pos]=1;
        for( k =1 ;  k <= N ; k++)
        {
            if(!vis[k] && (min + map[pos][k]) < low[k])
            {
                low[k]=min + map[pos][k];
            }
        }
    }
//    for(i = 1 ; i <= N ; i++)
//    printf("%.2lf ",low[i]);
//    puts("");
    return low[v1];
}
int main()
{
    int i,j,k;
    scanf("%d",&N);
    for(i = 0 ; i <= N ; i++)
    for(j = 0 ; j <= N ; j++)
    map[i][j]=1000000.0;
    for(i = 1 ; i <= N ; i++)
    {
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    scanf("%d",&M);
    for(i = 1 ; i++<= M;)
    {
        int sta,end;
        scanf("%d%d",&sta,&end);
        map[sta][end]=map[end][sta]=sqrt(pow((a[sta].x-a[end].x),2)+pow((a[sta].y-a[end].y),2));
//        printf("%lf \n",map[sta][end]);
    }
    int s,e;
    scanf("%d%d",&s,&e);
    printf("%.2lf\n",Dijk(s,e));
    return 0;
}


 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值