[lnsyoj1469/luoguP4644] Cleaning Shifts
题意
原题链接
给定 个区间 ,第 个区间拥有权值 ,求使用这些区间将区间 (包含所有 个区间)完全覆盖(两端点不需要重合)所需区间的权值最小值。
sol
一道板子题,本来是数据结构优化 DP,但是被最短路薄纱了。
考虑将每一个时间点视作一个节点,这样问题就转化为了从起始点到终止点的路径问题。将每个区间转化为一条 ,权值为 的边,注意由于端点不需要重合,因此需要将 个点拆成 个点,因此终点要 。
考虑相交的区间,可以再连接 ,权值为 的边。这样只需要求出 到 的最短路就可以解决问题了
注意会爆 int
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<LL, int> PII;
const int N = 100005, M = 200005;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int h[N], e[M], w[M], ne[M], idx;
int n, start, ed;
LL dist[N];
bool st[N];
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
void dijkstra(){
memset(dist, 0x3f, sizeof dist);
priority_queue<PII, vector<PII>, greater<PII>> heap;
dist[start] = 0;
heap.push({0, start});
while (!heap.empty()){
PII t = heap.top();
heap.pop();
if (st[t.y]) continue;
st[t.y] = true;
for (int i = h[t.y]; ~i; i = ne[i]){
int j = e[i];
if (dist[j] > dist[t.y] + w[i]) {
dist[j] = dist[t.y] + w[i];
heap.push({dist[j], j});
}
}
}
}
int main(){
memset(h, -1, sizeof h);
scanf("%d%d%d", &n, &start, &ed);
for (int i = start; i <= ed; i ++ ) add(i + 1, i, 0);
while (n -- ){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b + 1, c);
}
dijkstra();
printf("%lld\n", dist[ed + 1] == INF ? -1 : dist[ed + 1]);
}
分类:
题解 / 2024训练
标签:
图论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现