M isaka E
「——天明明是这么的蓝 前途却是一片黑暗」

[CCO2024] Treasure Hunt 解题思路

[CCO2024] Treasure Hunt

题目思路:

魔改SPFA

由于这道题只要求最大收益,没有要求记录路径,我们设 \(dis_i\)\(i\) 的最大收益。

显然,\(dis_i\) 的初始值可以设置为 \(v_i\) ,即在岛上不动所得到的收益。

对于点 \(i\) 所连接的的每一个点 \(j\) ,如果其收益小于当前点的收益减这个航线的花费,即 \(dis_j<dis_i-price_{ij}\) 我们可以将这个点进行松弛操作。

参考代码

#include<bits/stdc++.h>
using namespace std;
#define ll int
const int N = 1e6+10;
vector<pair<int,ll>> edge[N];
int n,m;
ll v[N],dis[N];
void bfs(int x){
    queue<pair<int,ll>> q;
    q.push(pair(x,v[x]));
    while (!q.empty())
    {
        int nw=q.front().first;
        ll pric=q.front().second;
        q.pop();
        if(pric<=dis[nw])continue;
        dis[nw]=pric;
        for(int i=0;i<edge[nw].size();++i){
            if(dis[edge[nw][i].first]>=dis[nw]-edge[nw][i].second)continue;
            q.push(pair(edge[nw][i].first,dis[nw]-edge[nw][i].second));
        }
    }
}
int main(){
    //freopen("read.in","r",stdin);
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)scanf("%d",&v[i]);
    for(int i=1;i<=m;++i){
        int l,r;ll c;
        scanf("%d%d%lld",&l,&r,&c);
        edge[l].push_back(pair(r,c));
        edge[r].push_back(pair(l,c));
    }
    for(int i=1;i<=n;++i)bfs(i);
    for(int i=1;i<=n;++i){
        printf("%d\n",dis[i]);
    }
    
}

posted @ 2025-03-13 13:44  MisakaE  阅读(39)  评论(0)    收藏  举报