J. Grammy and Jewelry
Grammy and Jewelry
这道题比赛的时候没有时间看,因为太菜了,比赛后三天才有时间看这道题。
这道题说的是给一个无向图,每一个节点都要价值为w的财宝,数量无限,求一个人从1节点出发,每走一条边消耗1个时间单位,需要将财宝带回1节点才算真正获得财宝,这些动作需要在t个时间单位中完成。
这题是一个完全背包+最短路问题,我们可以把时间t看做背包的容量,在途中花费的时间为获得财宝的所占用的时间,所以我们先求出头结点到其他结点的最短路径
代码如下
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 3e3 + 10;
typedef pair<int, int> PII;
int n, m, t, v[N];
int ne[N << 1], e[N << 1], h[N << 1], idx, w[N << 1]; //无向图,数组开大一点
int dist[N << 1];
int f[N];
bool vis[N << 1];
void add(int a, int b)
{
e[idx] = b, w[idx] = 1, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, 1});
while(!heap.empty())
{
PII r = heap.top();
heap.pop();
int ver = r.second;
if(vis[ver]) continue;
vis[ver] = 1;
for(int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if(dist[j] > dist[ver] + w[i])
{
dist[j] = dist[ver] + w[i];
heap.push({dist[j], j});
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> t; //t相当于完全背包中的体积
for(int i = 2; i <= n; i++) cin >> v[i];
memset(h, -1, sizeof h);
while(m--)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
dijkstra();
for(int i = 1; i <= n; i++)
{
for(int j = dist[i] * 2; j <= t; j++)//dist数组乘以2是因为来到结点还要将财宝放回到头结点,故乘2
{
f[j] = max(f[j], f[j - dist[i] * 2] + v[i]);
}
}
for(int i = 1; i <= t; i++)
cout << f[i] << ((i == t ) ? '\n' : ' ');
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现