zoukankan      html  css  js  c++  java
  • vijos 1880 变形最短路

    题意:Ninian 的魔力可以在结界间传递。
    结界中有 N 个光柱,第 i 个光柱的光压范围为 0~Ei 。魔力可以有 M 种传递,从光柱 Ai 传递到光柱 Bi ,花费时间 Ti 。
    当魔力从光压为 S 传递并花费了 T 的时间后,就会衰减到光柱上光压为 S-T 处,S-T 不能为负。
    Ninian 可以将魔力的光压花费 1 时间增加 1 或减少 1 ,当然魔力的光压不能超过光柱的光压范围,也不能小于 0 。
    Ninian 的魔力初始在 1 号光柱,光压为 X 。
    问 Ninian 的魔力到达第 N 个光柱且光压最大所需要的最少时间。

    链接:点我

    ans 因分为3个部分:1.中途增加光压的时间 2.中途减少光压的时间 3. 所有路程的总时间
    发现没有增加光压的话,dist是递减的,如果把每个柱子的光压下限0去掉后,光压无论在何时加都是一样的
    因为若从某刻光压小于等于0后,我们可以按需调整光压,不会出现降低光压这个操作,而不论如何最后的光压一定是h[n]
    所以

    1.光压无论在何时加都是一样的

    而我们又发现在路径上减少1个光压和在光柱上人为调整1个光压的时间是一样的
    光压差就是时间差
    我们用dist[n]表示到点n时的光压

    2.X-dist[终点]=中途减少光压的时间+所有路程的总时间

    又由1得E[终点]-dist[终点]=中途增加光压的时间

    这两个式子都是随着dist[终点]的递增而递减的
    只要算出最大的dist[终点]即可,这就是为什么要用最短路

    ans=(X-dist[终点])+(E[终点]-dist[终点)=X+E[终点]-2*dist[终点]

    以上是某大牛的题解

    ans=路上的消耗+总共需要充能多少

    我自己的理解是dist表示从起始点中间也充能到某点的消耗

    则x-dist[n]=路上的消耗

    e[i]-dist[n]=总共需要充能多少

    相加即为所求

     1 #include<cstdio>
     2 #include<queue>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=100005;
     7 const long long INF=0x3f3f3f3f;// >> 10^9*10^5
     8 int H[MAXN];
     9 long long dist[MAXN];
    10 vector<int> to[MAXN],cost[MAXN];
    11 struct Node{
    12     long long d;    //剩余能量
    13     int v;      //点编号
    14     Node(long long dd,int vv)
    15     {
    16         d=dd;
    17         v=vv;
    18     }
    19     friend bool operator<(Node a,Node b)
    20     {
    21         return a.d<b.d;
    22     }
    23 };
    24 int main(){
    25     /*#ifndef ONLINE_JUDGE
    26     freopen("1.in","r",stdin);
    27     #endif*/
    28     int N,M,X,A,B,T;
    29     scanf("%d%d%d",&N,&M,&X);
    30 
    31     for(int i=1;i<=N;i++) scanf("%d",&H[i]);
    32     for(int i=0;i<M;i++)
    33     {
    34         scanf("%d%d%d",&A,&B,&T);
    35         to[A].push_back(B);
    36         cost[A].push_back(T);
    37         to[B].push_back(A);
    38         cost[B].push_back(T);
    39     }
    40     for(int i=1;i<=N;i++) dist[i]=-INF;
    41     priority_queue<Node> q;
    42     q.push(Node(X,1));
    43 
    44     while(!q.empty())
    45     {
    46         Node now=q.top();
    47         q.pop();
    48         if(dist[now.v]!=-INF) continue;
    49         dist[now.v]=now.d;
    50         for(int i=0;i<to[now.v].size();i++)
    51         {
    52             int u=to[now.v][i];
    53             int c=cost[now.v][i];
    54             if(c>H[now.v]) continue;
    55             q.push(Node(min(now.d-c,(long long)H[u]),u));   //任意时刻都能充能量,能量不能溢出
    56         }
    57     }
    58     if(dist[N]==-INF) puts("-1");
    59     else printf("%lld
    ",X+H[N]-dist[N]*2);
    60 
    61     return 0;
    62 }
  • 相关阅读:
    浅谈Javascript数据属性与访问器属性
    深入浅析JavaScript中的constructor
    javascript 继承
    很认真的聊一聊程序员的自我修养
    JavaScript数据属性与访问器属性
    Js中的数据属性和访问器属性
    [javascript基础]constructor与prototype
    C# System.Net.Mail
    Execl (转)导入导出execl 全
    delegate 委托方法
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4507224.html
Copyright © 2011-2022 走看看