Codeforces Round #182 (Div. 1) B. Yaroslav and Time(二分+SPFA变形)

 

题目大意

 

有 n(3n100) 个站点,当第一次到达站点 u 的时候会增加寿命 au(1≤au≤103),题目给了 n 个站点的二位空间坐标,每两个站点之间的距离为曼哈顿距离(dis(i, j)=|xi-xj|+|yi-yj|),从站点 i 到达站点 j 需要的时间为 dis(i, j)*d(d 是题目给定的一个常数,且 103≤d≤105)。某个人最开始的时候在站点 1,他想到站点 n 去,问,他最开始至少剩下多少寿命才能活着到达站点 n?

 

做法分析

 

很容易想到二分寿命值,但是怎么判断在某个具体的寿命下,能否到达第 n 个站点呢?

注意题目给的数据范围:1≤au≤103 且 103≤d≤105

想到了什么?

对了,如果直接用 SPFA 跑一遍最长路,是不会在路径上出现重复节点的!如果出现重复节点就会形成一个负环,这样肯定不如前面的优!因为就算每到一个节点都增加以下寿命,由于寿命增加的肯定比在路上消耗的小,所以寿命是随着经过的节点的数量而递减的!

那么,每当遇见 f[u]-dis(i, u)*d+A[i]>f[i] (其中:f[u] 表示到达 u 节点剩余的最大寿命值,A[i] 表示第一次进入 i 节点增加的寿命值)的时候,肯定是从另一条路径到达的 i 节点。那么,我跑一遍 SPFA,看能不能到达 n 节点,这样,就判断出来了

 

参考代码

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdio>
 5 #include <queue>
 6 
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const int N=106;
11 
12 LL d, A[N], f[N];
13 bool vs[N];
14 int X[N], Y[N], n;
15 queue <int> q;
16 
17 inline LL dis(int a, int b)
18 {
19     return abs(X[a]-X[b])+abs(Y[a]-Y[b]);
20 }
21 
22 bool judge(LL init)
23 {
24     memset(f, -1, sizeof f);
25     while(!q.empty()) q.pop();
26     memset(vs, 0, sizeof vs);
27     q.push(1), f[1]=init, vs[1]=1;
28     while(!q.empty())
29     {
30         int u=q.front();
31         q.pop(), vs[u]=0;
32         for(int i=1; i<=n; i++)
33         {
34             if(dis(i, u)*d>f[u] || i==u) continue;
35             if(f[u]-dis(i, u)*d+A[i]>f[i])
36             {
37                 f[i]=f[u]-dis(i, u)*d+A[i];
38                 if(!vs[i]) q.push(i), vs[i]=1;
39             }
40         }
41     }
42     if(f[n]==-1) return false;
43     return true;
44 }
45 
46 int main()
47 {
48     scanf("%d%I64d", &n, &d);
49     for(int i=2; i<n; i++) scanf("%I64d", &A[i]);
50     for(int i=1; i<=n; i++) scanf("%d%d", &X[i], &Y[i]);
51     LL L=0, R=((1LL)<<60);
52     while(L<R)
53     {
54         LL mid=(L+R)>>1;
55         if(judge(mid)) R=mid;
56         else L=mid+1;
57     }
58     if(!judge(L)) L++;
59     printf("%I64d\n", L);
60     return 0;
61 }
B. Yaroslav and Time

 

题目链接 & AC通道

 

Codeforces Round #182 (Div. 1) B. Yaroslav and Time

 

 

 

posted @ 2013-05-16 18:57  jianzhang.zj  阅读(453)  评论(0编辑  收藏  举报