[codeforces] 854D. Jury Meeting(前/后缀最小值)
来源:互联网 发布:python 传参数 编辑:程序博客网 时间:2024/05/29 06:51
[codeforces] 854D. Jury Meeting
题目链接:
D. Jury Meeting
题目大意:
有n个人分别在1~n的点上, 要让这n个人到0号点并且所有人在一起的天数至少为k天, 之后再回到各自的点。 有m个航班, d f, t, c 表示第d天从u到v的花费为c, 其中f, t 必有一个是0。
输出最小花费, 如果不能满足输出-1。
数据范围:
解题思路:
刚开始思路方向是 找一个位置
我们先将所有航班按照日期排序, 正着扫一遍, 就可以维护第i天所有人到达0号点的最小和。 倒着扫一遍, 就是所有人第i天开始离开的最小和。
具体维护方法:每个人总是维护一个最小花费, n个人都出现过之后才开始更新
完事之后递推一遍更新。(更新前缀最小和)
倒着的同理。。 代码思路很清晰。
前缀和后缀都处理完之后我们就可以枚举位置维护答案了。
代码:
/******************************************** *Author* :ZZZZone *Created Time* : 四 9/ 7 22:09:41 2017 *Ended Time* : 四 9/ 7 23:04:05 2017*********************************************/#include<cstdio>#include<algorithm>#include<cmath>#include<cstdlib>#include<cstring>#include<vector>using namespace std;typedef long long LL;typedef pair<int , int> PII;const int MaxN = 1e5, MaxV = 1e6;const LL inf = 1LL << 60;int n, m, k;struct NODE{ int d, u, v, c;}box[MaxV + 5];int ok[MaxN + 5];LL f[MaxV + 5], t[MaxV + 5];bool cmp(NODE x, NODE y){ return x.d < y.d;}int main(){ while(~scanf("%d %d %d", &n, &m, &k)){ for(int i = 1; i <= m; i++) scanf("%d %d %d %d", &box[i].d, &box[i].u, &box[i].v, &box[i].c); sort(box + 1, box + m + 1, cmp); LL tot = 0; for(int i = 1; i <= 1e6; i++) f[i] = t[i] = inf; for(int i = 1; i <= m; i++){//前缀 if(box[i].u == 0) continue; if(ok[box[i].u] == 0){ ok[0]++; ok[box[i].u] = box[i].c; tot = tot + 1LL * box[i].c; } else{ tot = tot - ok[box[i].u]; ok[box[i].u] = min(ok[box[i].u], box[i].c); tot = tot + ok[box[i].u]; } if(ok[0] == n) f[box[i].d] = tot;//n个人都到达了才更新 } for(int i = 2; i <= 1e6; i++) f[i] = min(f[i], f[i - 1]);// 递推维护前缀 memset(ok, 0, sizeof(ok)); tot = 0; for(int i = m; i >= 1; i--){ if(box[i].v == 0) continue; if(ok[box[i].v] == 0){ ok[0]++; ok[box[i].v] = box[i].c; tot = tot + 1LL * box[i].c; } else{ tot = tot - ok[box[i].v]; ok[box[i].v] = min(ok[box[i].v], box[i].c); tot = tot + ok[box[i].v]; } if(ok[0] == n) t[box[i].d] = tot; } for(int i = 1e6 - 1; i >= 1; i--) t[i] = min(t[i], t[i + 1]); LL ans = inf; for(int i = 1; i <= 1e6 - k - 1; i++){ if(f[i] != inf && t[i + k + 1] != inf) ans = min(ans, f[i] + t[i + k + 1]); //printf("%lld %lld\n", f[i], t[i]); } if(ans != inf) printf("%lld\n", ans); else printf("-1\n"); } return 0;}
阅读全文
0 0
- [codeforces] 854D. Jury Meeting(前/后缀最小值)
- Codeforces 854D Jury Meeting【思维+前后缀和+二分】
- Codeforces 854 D Jury Meeting(前缀和后缀)
- Codeforces Round #433 (Div. 2) D. Jury Meeting(思维 贪心 前后缀)
- codeforces 854 D. Jury Meeting(dp水题)
- Codeforces 854 D. Jury Meeting(技巧)
- codeforces 854D Jury Meeting (思维、尺取)
- Codeforces Round #433 D. Jury Meeting
- codeforces 845D Jury Meeting(div.2)
- Codeforces Round #433 D. Jury Meeting
- CF 845D Jury Meeting 枚举断点+前缀后缀
- Jury Meeting CodeForces
- Codeforces Round #433Div. 2 D Jury Meeting 优先队列
- Codeforces Round #433 (Div. 2) D. Jury Meeting
- Codeforces Round #433 (Div. 2 D. Jury Meeting 二分
- Codeforces Round #433 (Div. 2) D. Jury Meeting
- Codeforces Round #433 Jury Meeting
- Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) D. Jury Meeting(贪心)
- mysql数据库的cmd命令总结(持续更新)
- [LintCode]480.二叉树的所有路径
- 图像缩放的双线性内插值算法的原理解析
- sql优化中的陷进
- Java定时器
- [codeforces] 854D. Jury Meeting(前/后缀最小值)
- YouTube推荐算法解读
- 自行车 前灯 泛光 散光 手电 推荐
- CodeForces
- 双线性插值原理与实现
- hibernate查询
- Kotlin中的集合(Collection)
- java Object 之 finalize 方法
- HDU 1086 You can Solve a Geometry Problem too(判定线段相交 规范相交和非规范相交)