最短路径(需要使用高精度整数)

该博客探讨了一道最短路径问题,由于路径距离较大,不适合使用int类型表示,因此采用大整数(bigint)进行计算。博主通过对比之前的方法,引入了一个flag数组来解决大整数比较时的问题。在判断是否更新最短路径时,利用flag数组的布尔值,只有当目标点未被更新或者新的路径长度更短时才更新。博客中提供了相应的源代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目网址:最短路径

题目解析:这道题的话,跟之前的题目相比就是他的距离是很大的数,所以不能使用int来表示,所以我定义了bigint来表示大整数,同时需要跟之前的一篇博客最短路径进行比对,那个里面定义了一个dist和mark数组,这里还需要一个flag数组,为什么呢,看过那篇博客的人可能知道,那我在判断是否需要更新的时候,我可能if(dist[i]==-1||dist[t]>dist[newp]+c)成立,那么我更新dist[t]的值,但是这里使用大整数了,我们函数重载==号,我是使用flag数组,如果这个点之前没有更新过,那么flag为false,那么更新条件就变成了if(flag[t]==false||dist[newp]+c<dist[t])成立才更新,其他就基本没什么变化了,下面贴出源码。。

#include<iostream>
#include<vector>
using namespace std;
struct bigint
{
    int digit[101];
    int size;
    void init()
    {
        for (int i = 0; i < 101; i++)
            digit[i] = 0;
        size = 0;
    }
    void set(string s)
    {
        init();
        int len = s.length();
        for (int i = len - 1, c = 1, j = 0, t = 0; i >= 0; i--)
        {
            t += (s[i] - '0')*c;
            c = c * 10;
            j++;
            if (j == 4 || i == 0)
            {
                digit[size++] = t;
                c = 1;
                j = 0;
                t = 0;
            }
        }
    }
    bigint operator +(const bigint &a)const{
        bigint E;
        E.init();
        int c = 0;
        for (int i = 0; i < size || i < a.size; i++)
        {
            int t = digit[i] + a.digit[i] + c;
            c = t / 10000;
            t = t % 10000;
            E.digit[E.size++] = t;
        }
        if (c != 0)
            E.digit[E.size++] = c;
        return E;
    }
    bigint operator *(int x)const{
        bigint E;
        E.init();
        int c = 0;
        for (int i = 0; i < size; i++)
        {
            int t = digit[i] * x+c;
            c = t / 10000;
            t = t % 10000;
            E.digit[E.size++] = t;
        }
        if (c != 0)
            E.digit[E.size++] = c;
        return E;
    }
    int  operator %(int x)const{
        int c = 0;
        for (int i = size - 1; i >= 0; i--)
        {
            c = (c * 10000 + digit[i]) % x;
        }
        return c;
    }
    bool operator <(const bigint &a)const{
        if (size != a.size)
            return size<a.size;
        else
        {
            for (int i = size - 1; i >= 0; i--)
            {
                if (digit[i] != a.digit[i])
                    return digit[i] < a.digit[i];
            }
        }
    }
};
struct E
{
    int next;
    bigint cost;
};
vector<E> edge[1001];
bool mark[1001];
bool flag[1001];//false为不可达
bigint dist[1001];
int main()
{
    int n, m;
    while (cin >> n >> m&&n&&m)
    {
        //初始化
        for (int i = 0; i < n; i++)
        {
            edge[i].clear();
            mark[i] = false;
            flag[i] = false;
            dist[i].init();
        }
        bigint c;
        c.set("1");
        for (int i = 0; i < m; i++){
            int a, b;
            cin >> a >> b;
            E tmp;
            tmp.next = b;
            tmp.cost = c;
            edge[a].push_back(tmp);
            tmp.next = a;
            edge[b].push_back(tmp);
            c = c * 2;
        }
        int newop = 0;
        mark[0] = true;
        flag[0] = true;
        dist[0].set("0");
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < edge[newop].size(); j++)
            {
                int t = edge[newop][j].next;
                bigint c = edge[newop][j].cost;
                if (mark[t])
                    continue;
                if (flag[t] == false || c + dist[newop] < dist[t])
                {
                    flag[t] = true;
                    dist[t] = c + dist[newop];
                }
            }
            bigint min;
            min.set("999999999999999999999999999999999999");
            for (int j = 0; j < n; j++)
            {
                if (mark[j])
                    continue;
                if (flag[j] == false)
                    continue;
                if (dist[j] < min)
                {
                    min = dist[j];
                    newop = j;
                }
            }
            mark[newop] = true;
        }
        for (int i = 1; i < n; i++)
        {
            if (flag[i] == false)
                cout << "-1" << endl;
            else
                cout << dist[i] % 100000 << endl;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1100
    User: hellosyqq
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:2768 kb
****************************************************************/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值