描述
学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.
可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.
好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.
其中第i位朋友说:
如果doc有不少于Ri元钱,
doc可以把手上所有的钱都给这位朋友,
并从这位朋友手中换回Vi元钱,
但是这次交换会浪费Ti的时间.
doc希望可以在最短的时间内换到M元钱(其实是可以大于M的, 因为doc可以存私房钱呢), 否则学姐会生气的!
格式
输入格式
输入数据第一行给定T, 表示总的询问次数.
对于每一次询问, 第一行给出两个整数N和M.
之后N行, 每一行给出三个整数Vi, Ri和Ti. (保证Ri<=Vi).
输出格式
对于每一次询问, 首先输出询问的编号, 参见样例输出.
之后输出最小需要的时间, 如果不可能完成目标, 则输出-1.
样例1
样例输入1
3
5 9
5 1 1
10 4 10
8 1 10
11 6 1
7 3 8
4 5
2 1 1
3 2 1
4 3 1
8 4 1
3 10
5 1 3
8 2 5
10 9 2
样例输出1
Case #1: 10
Case #2: 4
Case #3: -1
限制
对于40%的数据
N <= 1500.
对于100%的数据
T <= 5
1 <= N <= 100000.
1 <= M <= 1000000000.
1 <= Ri <= Vi <= 1000000000.
1 <= Ti <= 1000000000.
蒟蒻并没有看懂sdfzgxk的题解orz……
然而看到了这样一句话“用f[i]表示从大于等于m的点到i的最短时间”
这……好像可以单源最短路,翻sdfzwxl的题解,可写
并不清楚long long下怎么赋极值
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 int t,n,m,cnt,tot; 8 struct dt{ 9 int s,e; 10 long long v; 11 }road[200010]; 12 struct data{ 13 int next,to; 14 long long dis; 15 }edge[400010]; 16 int num[400010],head[200010]; 17 long long w[200010]; 18 bool check[200010]; 19 queue<int>q; 20 void add(int start,int end,long long dd){ 21 edge[++tot].next=head[start]; 22 edge[tot].to=end; 23 edge[tot].dis=dd; 24 head[start]=tot; 25 } 26 void spfa(){ 27 memset(w,0x3f3f3f3f,sizeof(w)); 28 check[1]=1; 29 w[1]=0; 30 q.push(1); 31 while(!q.empty()){ 32 int u=q.front(); 33 q.pop(); 34 check[u]=0; 35 for(int i=head[u];i;i=edge[i].next) 36 if(w[edge[i].to]>w[u]+edge[i].dis){ 37 w[edge[i].to]=w[u]+edge[i].dis; 38 if(!check[edge[i].to]){ 39 check[edge[i].to]=1; 40 q.push(edge[i].to); 41 } 42 } 43 } 44 } 45 int main(){ 46 scanf("%d",&t); 47 for(int ii=1;ii<=t;ii++){ 48 memset(head,0,sizeof(head)); 49 cnt=0; 50 tot=0; 51 scanf("%d%d",&n,&m); 52 for(int i=1;i<=n;i++){ 53 scanf("%d%d%lld",&road[i].s,&road[i].e,&road[i].v); 54 if(road[i].s>m) road[i].s=m; 55 if(road[i].e>m) road[i].e=m; 56 num[++cnt]=road[i].s; 57 num[++cnt]=road[i].e; 58 } 59 sort(num+1,num+cnt+1); 60 cnt=unique(num+1,num+cnt+1)-num-1; 61 for(int i=1;i<=n;i++){ 62 road[i].s=lower_bound(num+1,num+cnt+1,road[i].s)-num; 63 road[i].e=lower_bound(num+1,num+cnt+1,road[i].e)-num; 64 add(road[i].e,road[i].s,road[i].v); 65 } 66 for(int i=2;i<=cnt;i++) add(i,i-1,0); 67 spfa(); 68 if(w[cnt]==0x3f3f3f3f) printf("Case #%d: -1 ",ii); 69 else printf("Case #%d: %lld ",ii,w[cnt]); 70 } 71 return 0; 72 }