最短路 自己觉得较快的(没有用栈优化的)

先附上代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <memory.h>
#include <queue>
#define N 999999
using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    int x[N], y[N];
    int i;
    for(i = 1; i <= n; i++)
    {
        scanf("%d %d", &x[i], &y[i]);
    }
    int u[N], v[N];
    double w[N];//放权值的平方
    int m;
    scanf("%d", &m);
    m *= 2;
    for(i = 0; i < m; i++)
    {
        int a, b;
        scanf("%d %d", &a, &b);
        u[i] = a, v[i] = b;
        double tt = pow((x[a] - x[b]), 2) + pow((y[a] - y[b]), 2);
//        printf("%.2lf\n", tt);
        w[i] = 1.0 * sqrt(tt);
        i++;
        u[i] = b; v[i] = a;
        w[i] = w[i - 1];
    }
//    for(i = 0; i < m; i++)
//    {
//        printf("%d %d %.2lf\n", u[i], v[i], w[i]);
//    }
    int s, t;
    scanf("%d %d", &s, &t);
    double dis[N];
    for(i = 1; i <= n; i++)
    {
        dis[i] = INT_MAX;
    }
    dis[s] = 0;
    for(i = 0; i < n - 1; i++)
    {
        int j;
        int check = 0;
        for(j = 0; j < m; j++)
        {
            if(dis[v[j]] > dis[u[j]] + w[j])
            {
                dis[v[j]] = dis[u[j]] + w[j];
                check = 1;
            }
        }
        if(check == 0)
            break;
    }
    printf("%.2lf\n", dis[t]);
    return 0;
}

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

1.第一次没有加memset的头文件
2.把公式理解错了,以为是所有平方和后的开放(错的)
3.理解最后的每边松弛有些问题
4.N定义的太小了,因为咱也不知道有多少边
哎,细心呀,这个算法还是较快的,也算是好理解的,是一个总结出的代码
比链式前向星储存好记一些吧!!

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <memory.h>
using namespace std;

int main()
{
    int n, m, i, j, k;
    while (~scanf("%d %d", &n, &m))
    {
        int u[200000], v[200000], w[200000];
        int first[200000], next[200000];
        int dis[200000] = {0}, book[200000] = {0};
        int que[200000] = {0}, head = 1, tail = 1;
        int inf = 99999999;
        for (i = 1; i <= n; i++)
        {
            dis[i] = inf;
        }
        dis[1] = 0;
        for (i = 1; i <= n; i++)
        {
            book[i] = 0;
        }
        for (i = 1; i <= n; i++)
        {
            first[i] = -1;
        }
        for (i = 1; i <= m * 2; i++)
        {
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);
            u[i] = a, v[i] = b, w[i] = c, next[i] = first[u[i]];
            first[u[i]] = i;
            i++;
            u[i] = b, v[i] = a, w[i] = c, next[i] = first[u[i]];
            first[u[i]] = i;
        }
        que[tail] = 1;
        tail++;
        book[1] = 1;
        while (head < tail)
        {
            k = first[que[head]];
            while (k != -1)
            {
                if(dis[v[k]] > dis[u[k]] + w[k])
                {
                    dis[v[k]] = dis[u[k]] + w[k];
                    if (book[v[k]] == 0)
                    {
                        que[tail] = v[k];
                        tail++;
                        book[v[k]] = 1;
                    }
                }
                k = next[k];
            }
            book[que[head]] = 0;
            head++;
        }
        printf("%d\n", dis[n]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值