[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]);
}
}

浙公网安备 33010602011771号