acwing 341

该博客讨论了一种图论问题的解决方案,涉及两种类型的边:单向和双向。通过Dijkstra算法寻找从源节点1到所有其他节点的最短路径,并使用广度优先搜索找到从目标节点n到所有其他节点的最大路径。最终,找出两者之间的最大差值作为输出。

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

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 100, M = 5e5 + 100;
int head1[N], ver1[M], e1[M],  tot1;
int head2[N], ver2[M], e2[M],  tot2;
int d1[N], d2[N];
bool v1[N], v2[N];
int price[N];
int n, m;

void add1(int x, int y)
{
    ++ tot1;
    ver1[tot1] = y;
    e1[tot1] = head1[x];
    head1[x] = tot1;
}

void add2(int x, int y)
{
    ++ tot2;
    ver2[tot2] = y;
    e2[tot2] = head2[x];
    head2[x] = tot2;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> price[i];
    for (int i = 1; i <= m; i ++)
    {
        int x, y, z;
        cin >> x >> y >> z;
        if (z == 1)
        {
            add1(x, y);
            add2(y, x);
        }
        else
        {
            add1(x, y);
            add1(y, x);
            add2(x, y);
            add2(y, x);
        }
    }
    
    memset(d1, 0x3f, sizeof d1);
    memset(v1, false, sizeof v1);
    d1[1] = price[1];
    queue<int> q1;
    q1.push(1);
    while (q1.size())
    {
        int x = q1.front(); q1.pop();
        v1[x] = false;
        for (int i = head1[x]; i; i = e1[i])
        {
            int y = ver1[i];
            int t = min(d1[x], price[y]);
            if (d1[y] > t)
            {
                d1[y] = t;
                if (!v1[y])
                {
                    q1.push(y);
                    v1[y] = true;
                }
            }
        }
    }
    memset(d2, 0, sizeof d2);
    memset(v2, false, sizeof v2);
    d2[n] = price[n];
    queue<int> q2;
    q2.push(n);
    while (q2.size())
    {
        int x = q2.front(); q2.pop();
        v2[x] = false;
        for (int i = head2[x]; i; i = e2[i])
        {
            int y = ver2[i];
            int t = max(d2[x], price[y]);
            if (d2[y] < t)
            {
                d2[y] = t;
                if (!v2[y])
                {
                    v2[y] = true;
                    q2.push(y);
                }
            }
        }
    }
    
    int mx = 0;
    for (int i = 1; i <= n; i ++) mx = max(mx, d2[i] - d1[i]);
    cout << mx;
    /*for (int i = 1; i <= n; i ++)
    {
        cout << d1[i] << " " << d2[i] << endl;
    }*/
    return 0;
}

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值