A - Environment-Friendly Travel(二维dijkstra)

 二维dijkstra, d i s [ i ] [ j ] dis[i][j] dis[i][j] 代表从起点出发,经过 j j j 长度的路程,到达 i i i 点的最小价值。写法就和dijkstra模板差不多了。
 对于 p r i o r i t y q u e u e priority_queue priorityqueue 则重载一个结构体放进去,维护 C O 2 CO_2 CO2 的排放、路程的长度已经当前节点。

struct node
{
    int c, d, u;
    bool operator < (const node &a) const
    {
        if(c == a.c) return d > a.d;      // '>' 是最小值在上面,不要搞反
        return c > a.c;
    }
};
priority_queue<node>q;

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define int long long
const LL Max = 0x3f3f3f3f3f3f3f3f;
const LL Min = -0x3f3f3f3f3f3f3f3f;
const int N = 1e3 + 5;
typedef pair<int, int> PII;
int T, n, m, mxd, ans = Max;
int x[N], y[N], w[N];
int co[N][N];
bool st[N][N];
vector<PII> v[N];

struct node
{
    int c, d, u;
    bool operator < (const node &a) const
    {
        if(c == a.c) return d > a.d;
        return c > a.c;
    }
};
priority_queue<node>q;

int get(int i, int j)
{
    double d = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
    int x = d;
    if (x == d)
        return x;
    return x + 1;
}

void dijkstra()
{
    co[n][0] = 0;
    q.push({0, 0, n});
    while(q.size())
    {
        int t1 = q.top().c, t2  = q.top().d, t3 = q.top().u;
        // cout << t1 << " " << t2 << " " << t3 << '\n';
        q.pop();
        if(st[t3][t2]) continue;
        st[t3][t2] = true;
        for(int i = 0; i < v[t3].size(); i ++)
        {
            int j = v[t3][i].first, mj = v[t3][i].second;
            int dd = get(t3, j), ww = dd * w[mj];
            if(dd + t2 > mxd) continue;
            if(co[j][dd + t2] > co[t3][t2] + ww)
            {
                co[j][dd + t2] = co[t3][t2] + ww;
                q.push({co[j][dd + t2], dd + t2, j});
            }
        }
    }
}

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int s1, s2, t1, t2;
    cin >> s1 >> s2 >> t1 >> t2;
    cin >> mxd;
    cin >> w[0];
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> w[i];
    }
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> x[i] >> y[i];
        int k;
        cin >> k;
        while (k--)
        {
            int j, mj;
            cin >> j >> mj;
            v[i].push_back({j, mj});
            v[j].push_back({i, mj});
        }
        v[n].push_back({i, 0});
        v[i].push_back({n + 1, 0});
    }
    v[n].push_back({n+1, 0});
    x[n] = s1, y[n] = s2, x[n + 1] = t1, y[n + 1] = t2;
    if(get(n, n+1) > mxd)
    {
        cout << "-1\n";
        return 0;
    }
    memset(co, 0x3f, sizeof co);
    dijkstra();

    for(int i = 0; i <= mxd; i ++)
    {
        ans = min(ans, co[n+1][i]);
    }
    cout << ans << '\n';
    return 0;
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值