Vijos P1901 学姐的钱包
2016-11-09 21:38
246 查看
描述
学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.
可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.
好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.
其中第i位朋友说:
如果doc有不少于Ri元钱,
doc可以把手上所有的钱都给这位朋友,
并从这位朋友手中换回Vi元钱,
但是这次交换会浪费Ti的时间.
doc希望可以在最短的时间内换到M元钱(其实是可以大于M的, 因为doc可以存私房钱呢), 否则学姐会生气的!
【题目分析】
无意中发现了这样一道题目,原题解出自学长的博客【魔法传送门】
但是看不懂他的题解(看了一眼没看懂),然而整个网上只有他一个人的题解(还有一个是流氓网站用爬虫抄的)。(线段树解法)
然后自己来思考这道题目好了。
其实画到数轴上就是一个区间转移到一个值。那么为了保证过程的最优,可以把区间抽象成最左边的一个点,那么区间左端端点到一个值连一条边权为时间的边。再考虑到钱较多时可以通过少部分钱的状况进行转移,那么就可以把每个点向左面的点连一条边权为0的点,跑SPFA就可以了。
由于数据过大需要离散化,并且需要开long long。
(要不是网上没有好的题解我是不会写的)
【代码】
学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.
可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.
好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.
其中第i位朋友说:
如果doc有不少于Ri元钱,
doc可以把手上所有的钱都给这位朋友,
并从这位朋友手中换回Vi元钱,
但是这次交换会浪费Ti的时间.
doc希望可以在最短的时间内换到M元钱(其实是可以大于M的, 因为doc可以存私房钱呢), 否则学姐会生气的!
【题目分析】
无意中发现了这样一道题目,原题解出自学长的博客【魔法传送门】
但是看不懂他的题解(看了一眼没看懂),然而整个网上只有他一个人的题解(还有一个是流氓网站用爬虫抄的)。(线段树解法)
然后自己来思考这道题目好了。
其实画到数轴上就是一个区间转移到一个值。那么为了保证过程的最优,可以把区间抽象成最左边的一个点,那么区间左端端点到一个值连一条边权为时间的边。再考虑到钱较多时可以通过少部分钱的状况进行转移,那么就可以把每个点向左面的点连一条边权为0的点,跑SPFA就可以了。
由于数据过大需要离散化,并且需要开long long。
(要不是网上没有好的题解我是不会写的)
【代码】
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define ll long long int T,n,m; struct node{int v,r,t;}a[100001]; ll dis[300001],inf; int inq[300001]; int h[300001],ne[1000001],to[1000001],w[1000001],en=0; int ls[500001],top=0,kas=0; void add(int a,int b,int c) { ne[en]=h[a]; to[en]=b; w[en]=c; h[a]=en++; } void spfa() { memset(dis,0x3f,sizeof dis); inf=dis[0]; inq[1]=1; dis[1]=0; queue<int>q; q.push(1); while (!q.empty()) { int x=q.front(); q.pop(); inq[x]=0; for (int i=h[x];i>=0;i=ne[i]) { if (dis[to[i]]>dis[x]+w[i]) { dis[to[i]]=dis[x]+w[i]; if (!inq[to[i]]) { q.push(to[i]); inq[to[i]]=1; } } } } } int main() { scanf("%d",&T); while (T--) { memset(h,-1,sizeof h); en=0; scanf("%d%d",&n,&m); top=0; for (int i=1;i<=n;++i) { scanf("%d%d%d",&a[i].v,&a[i].r,&a[i].t); if (a[i].v>m) a[i].v=m; if (a[i].r>m) a[i].r=m; ls[++top]=a[i].v; ls[++top]=a[i].r; } sort(ls+1,ls+top+1); top=unique(ls+1,ls+top+1)-ls-1; for (int i=1;i<=n;++i) { a[i].v=lower_bound(ls+1,ls+top+1,a[i].v)-ls; a[i].r=lower_bound(ls+1,ls+top+1,a[i].r)-ls; add(a[i].r,a[i].v,a[i].t); } for (int i=2;i<=top;++i) add(i,i-1,0); spfa(); printf("Case #%d: %lld\n",++kas,dis[top]==inf?-1:dis[top]); } }
相关文章推荐
- Vijos1901 学姐的钱包
- Vijos P1901 学姐的钱包
- Vijos 1901 学姐的钱包(线段树优化dp)
- vijosP1901学姐的钱包
- spfa vijos1901 学姐的钱包
- 学姐吃牛排[Vijos1987]解题报告
- vijos1891 学姐的逛街计划(线性规划)
- vijos1904 学姐的幸运数字
- vijos1901 学姐的钱包
- vijos1891 学姐的逛街计划(线性规划)
- 【暴力】vijos P1897 学姐吃牛排
- 2014.11.12模拟赛【美妙的数字】| vijos1904学姐的幸运数字
- 【vijos1900】 学姐吃寿司
- 纪念cynthia的钱包和我的aiwa随身听,希望看我blog的朋友坐车时当心小偷!
- 万恶的小偷,还我钱包来!
- 钱包里的3句话
- 来自学哥、学姐关于网上投简历的一些经验分享
- 人弃我取的道道 撿钱包投资哲学之二
- 关于PBOC电子钱包的复合交易
- PBOC电子钱包规范简介