• [vijos P1880]ファーラの力


    据说这是一道 JOI 的题?反正我觉着挺好的喵~

    题目看起来十分可怕,但是代码还是很短的

    显而易见的,ans 因分为3个部分:1.中途增加光压的时间 2.中途减少光压的时间 3. 所有路程的总时间

    发现如果把每个柱子的光压下限0去掉后,光压无论在何时加都是一样的

    因为若从某刻光压小于等于0后,我们可以按需调整光压,就不再出现人为降低光压这个操作,而不论如何最后的光压一定是 E[终点]

    所以

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

    而我们又发现在路径上减少1个光压和在光柱上人为调整1个光压的时间是一样的

    光压差就是时间差

    我们用dist[n]表示到点n时的光压

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

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

    这两个式子都是随着dist[终点]的递增而递减的

    只要算出最大的dist[终点]即可,这就是为什么要用最短路稍的原因

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

     1 #include <cstdio>
     2 #include <queue>
     3 #include <algorithm>
     4 typedef std::pair<long long, int> node;
     5 const long long INF=0x7FFFFFFFFFFFFFLL;
     6 const int sizeOfPoint=100001;
     7 const int sizeOfEdge=600006;
     8 
     9 struct edge {int point, dist; edge * next;};
    10 edge memory[sizeOfEdge], * port=memory;
    11 edge * e[sizeOfPoint];
    12 inline edge * newedge(int point, int dist, edge * next)
    13 {
    14     edge * ret=port++;
    15     ret->point=point; ret->dist=dist; ret->next=next;
    16     return ret;
    17 }
    18 
    19 int N, M, X;
    20 int E[sizeOfPoint];
    21 long long dist[sizeOfPoint];
    22 std::priority_queue<node> q;
    23 inline long long min(long long x, long long y) {return x<y?x:y;}
    24 inline int getint();
    25 inline void putint(long long);
    26 
    27 int main()
    28 {
    29     N=getint(), M=getint(), X=getint();
    30     for (int i=1;i<=N;i++) E[i]=getint();
    31     for (int i=0;i<M;i++)
    32     {
    33         int A, B, T;
    34         A=getint(), B=getint(), T=getint();
    35         if (E[A]>=T) e[A]=newedge(B, T, e[A]);
    36         if (E[B]>=T) e[B]=newedge(A, T, e[B]);
    37     }
    38 
    39     for (int i=1;i<=N;i++) dist[i]=-INF;
    40     for (q.push(node(X, 1));!q.empty(); )
    41     {
    42         node u=q.top(); q.pop();
    43         if (dist[u.second]!=-INF) continue;
    44         dist[u.second]=u.first;
    45         for (edge * i=e[u.second];i;i=i->next)
    46             q.push(node(min(u.first-i->dist, E[i->point]), i->point));
    47     }
    48 
    49     if (dist[N]==-INF) printf("-1
    ");
    50     else putint(X+E[N]-(dist[N]<<1));
    51 
    52     return 0;
    53 }
    54 inline int getint()
    55 {
    56     register int num=0;
    57     register char ch;
    58     do ch=getchar(); while (ch<'0' || ch>'9');
    59     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
    60     return num;
    61 }
    62 inline void putint(long long num)
    63 {
    64     char stack[22];
    65     register int top=0;
    66     if (num==0) stack[top=1]='0';
    67     for ( ;num;num/=10) stack[++top]=num%10+'0';
    68     for ( ;top;top--) putchar(stack[top]);
    69     putchar('
    ');
    70 }
    本傻装B系列
  • 相关阅读:
    拥抱函数式编程 I
    关于CMS的那点事 I
    常用正规表达式
    javascript source map 的使用
    架构师修炼 后记
    CSS 天坑 I
    架构师修炼 III
    架构师修炼 II
    win10,VM14 安装cnetos6.9 虚拟机黑屏和只有光标闪烁解决办法
    C/C++数组初始化
  • 原文地址:https://www.cnblogs.com/dyllalala/p/4060253.html
Copyright © 2020-2023  润新知