C--最短路(Bellman-Ford算法)

C--最短路

Time Limit: 7000MS Memory Limit: 65536KB
Problem Description
给出一个带权无向图,包含n个点,m条边。求出s,e的最短路。保证最短路存在。
Input
 多组输入。
对于每组数据。
第一行输入n,m(1<= n && n<=5*10^5,1 <= m && m <= 2*10^6)。
接下来m行,每行三个整数,u,v,w,表示u,v之间有一条权值为w(w >= 0)的边。
最后输入s,e。
Output
 对于每组数据输出一个整数代表答案。
Example Input
3 1
1 2 3
1 2
Example Output
3
Hint
 
Author
 zmx
#include <bits/stdc++.h>

using namespace std;

int dis[500004], i, k, n, m, check, u[4000004], v[4000004], w[4000004];
void Bellman();
int main()
{
    int s, e, x, y, z, t;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        t = 1;
        for(i = 1; i <= m; i++)
            {
            scanf("%d %d %d", &x, &y, &z);
            u[t] = x, v[t] = y, w[t] = z;
            t++;
            u[t] = y, v[t] = x, w[t] = z;
            t++;
            }
        scanf("%d %d", &s, &e);
        m = m * 2;
        for(i = 1; i <= n; i++)
            dis[i] = INT_MAX;
        dis[s] = 0;
        Bellman();
        printf("%d\n", dis[e]);
    }
    return 0;
}
void Bellman()   //Bellman-Ford 算法
{
    for(k = 1; k < n; k++)
        {
            check = 0;
            for(i = 1; i <= m; i++)
                {
                    if(dis[u[i]] != INT_MAX && dis[v[i]] > dis[u[i]] + w[i]) //如果不判断dis是否为最大值,可能会溢出
                        {
                            dis[v[i]] = dis[u[i]] + w[i];
                            check = 1;
                        }
                }
            if(check == 0)
                break;
        }
        return ;
}

队列优化后
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;

int u[4000005], v[4000005], w[4000005];
int first[500005], next[4000005];
int dis[500005], book[500005];

int main()
{
    int x, y, z, n, m, s, e, t, i, k;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        t = 1;
        queue<int>q;
        for(i = 1; i <= n; i++)
            {
            dis[i] = inf;
            first[i] = -1;
            book[i] = 0;
            }
        for(i = 1; i <= m; i++)
            {
            scanf("%d %d %d", &x, &y, &z);
            u[t] = x, v[t] = y, w[t] = z;
            next[t] = first[u[t]];
            first[u[t]] = t;
            t++;
            u[t] = y, v[t] = x, w[t] = z;
            next[t] = first[u[t]];
            first[u[t]] = t;
            t++;
            }
        m = m * 2;
        scanf("%d %d", &s, &e);
        dis[s] = 0;
        q.push(s);
        book[s] = 1;
        while(q.size() > 0)
        {
            k = first[q.front()];
            book[q.front()] = 0;
            q.pop();
            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)
                            {
                                q.push(v[k]);
                                book[v[k]] = 1;
                            }
                    }
                k = next[k];
            }
        }
        printf("%d\n", dis[e]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值