首页 > 其他分享 >[ABC204E] Rush Hour 2 题解

[ABC204E] Rush Hour 2 题解

时间:2023-06-05 13:34:59浏览次数:47  
标签:Node Rush include idx int 题解 ABC204E now dis

Rush Hour 2

题目大意

给定一张无向图,边带两个参数 \(c_i,d_i\),在 \(t\) 时间时经过第 \(i\) 条边所需的时间是 \(c_i+\lfloor\frac{d_i}{t+1}\rfloor\),求在时间 \(0\) 时出发,在每个点可以停留非负整数时间,从点 \(1\) 到点 \(n\) 所需的最短时间。

思路分析

首先,容易发现在时间 \(t\) 时经过第 \(i\) 条边后的总时间是:\(t+c_i+\lfloor\frac{d_i}{t+1}\rfloor\)。

那么不妨设函数 \(f(t)=t+c_i+\lfloor\frac{d_i}{t+1}\rfloor\),由均值不等式容易得 \(f(t)_{\min}=f(\sqrt{d_i}-1)\)。

也就是说,当我们想经过某一条边时,如果当前时间大于 \(\sqrt {d_i}-1\),那么不用等待直接通过,否则等到 \(\sqrt{d_i}-1\) 时再通过。

那么就可以使用普通的 Dijkstra 解决了。

代码

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;
#define int long long
const int N=200100;

int n,m,idx=1,in1,in2,in3,in4;
int to[N],nxt[N],head[N];
int fa[N],vis[N];
int dis[N],c[N],d[N];

int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}

void add(int u,int v,int x,int y){
    idx++;to[idx]=v;nxt[idx]=head[u];head[u]=idx;c[idx]=x;d[idx]=y;
}

struct Node{
    int x,time;
    bool operator < (const Node &b) const{
        return time>b.time;
    }
}now;

priority_queue <Node> q;

void Dijkstra(){
    memset(dis,0x3f,sizeof dis);
    dis[1]=0;q.push(Node{1,0});
    while(!q.empty()){
        now=q.top();q.pop();
        if(vis[now.x]) continue;
        vis[now.x]=1;
        for(int i=head[now.x];i;i=nxt[i]){
            int v=to[i],t;
            if(now.time<=round(sqrt(d[i]))-1) t=round(sqrt(d[i]))-1;
            else t=now.time; //判断通过时间
            if(dis[v]>t+c[i]+d[i]/(t+1)){
                dis[v]=t+c[i]+d[i]/(t+1);
                q.push(Node{v,dis[v]});
            }
        }
    }
}

signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        scanf("%lld%lld%lld%lld",&in1,&in2,&in3,&in4);
        add(in1,in2,in3,in4);add(in2,in1,in3,in4);
        fa[find(in1)]=find(in2);
    }
    if(find(1)!=find(n)){cout<<"-1\n";return 0;}//并查集判连通
    Dijkstra();
    cout<<dis[n]<<'\n';
    return 0;
}

标签:Node,Rush,include,idx,int,题解,ABC204E,now,dis
From: https://www.cnblogs.com/TKXZ133/p/17457551.html

相关文章

  • P2487 拦截导弹 题解
    拦截导弹题目大意给定若干元素,每个元素有\(3\)个属性\(t_i,h_i,v_i\),求出一个使得对于\(\foralli,j,i>j\),\(t_i>t_j,h_i\leh_j,v_i\lev_j\)均成立的最长的子序列\(a\)的长度。并计算每个元素在所有的可能的\(a\)方案中的出现概率。思路分析先看第一个问题:按\(......
  • P5012 水の数列 题解
    水の数列题目大意对于给定的数列\(a\),选择一个数\(x\),定义其得分为数列中所有小于等于\(x\)的数形成的若干个连续区间的平方和除以\(x\)所得到的数。现进行多次询问,每次询问给定两个数\(l,r\),要求出一个得分最大的\(x\),满足数列中所有小于等于\(x\)的数形成的若干个......
  • [ABC201D] Game in Momotetsu World 题解
    GameinMomotetsuWorld题目大意在一个\(n\timesm\)的网格中,存在红色和蓝色两种格子,红色格子用-表示,蓝色格子用+表示。现在Takahashi和Aoki要在这个网格中进行游戏,游戏的规则如下:初始时,有一枚棋子摆放在左上角,即\((1,1)\)的位置。两名玩家的分数均为\(0\)。......
  • P2048 超级钢琴 题解
    超级钢琴题目大意求出序列中长度在\([L,R]\)中的所有区间的区间和前\(k\)大的区间的区间和。思路分析暴力做法是把所有符合条件的区间扔进堆里,再弹出\(k\)个,时间复杂度\(O((n^2+k)\logn)\),可以拿到\(20\text{pts}\)的好成绩。但真的有必要全部加进去吗?不!我们设五......
  • P5445 路灯 题解
    路灯题目大意在\(n+1\)个站点之间有\(n\)盏路灯,给定\(0\)时刻所有路灯的亮灭情况,在接下来的\(q\)个时刻,每时刻会发生以下两种事件之一:切换某一盏路灯的亮灭。询问两点之间存在多少时刻使得两点之间的路灯全部亮起。思路分析一道不错的数据结构。首先分析题目......
  • Mysql 主从备份 Last_Errno: 1146 Last_Error: Error executing row event: 错误问题
    本人在做主从备份的时候发现了此问题! 1主数据库是已经把这个表删除了丛数据库也是没有备份这个表但是一直报这个错原因是bin-log日志有这个表 但是没记录到已经把这个表删除了 主从表同步实际从库是根据主库的bin-log二进制的SQL进行执行的 这是Mysql的一个BUG1......
  • erlang实现长连接管理问题解决
    具体参见:http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1/1.    erlang进程增加了休眠特性hibernate,支持连接从20w->70w;如上面的文章里面所说,使用hibernate后支撑的长连接飞涨。2.    40w时系统出现异常。查看系统日志发现socket......
  • CF1818D 题解
    一、题目描述:给你一颗$n$个点,$m$条边的简单无向图,可能不连通。我们定义$鱼图$为满足以下条件的无向图:$包含恰好\1\个环,环上有\1\个特殊的结点\u\,u\除了连在环上的\2\条边外还正好有\2\条边连向不在此环上的结点。$求是否存$鱼图$。若存......
  • 题解
    原题请见题目链接1.暴力求解这是我们线下水题赛的T1这里为初学者提供一个思路,假设我们现在刚入OI,在考场上如何怎么优雅的避免保灵显然我们只要用一个\(O(n)\)的暴力去扫描就行了,但是直接向后扫\(i+1,i+2\)这样走很容易寄。因为你在\(i+1\)跳的时候很容易把后面跳过了......
  • 【题解】[ABC304F] Shift Table(容斥)
    【题解】[ABC304F]ShiftTable题目链接ABC304F题意概述Takahashi和Aoki将在接下来的\(N\)天里兼职工作。Takahashi这\(n\)天的出勤情况由字符串\(S\)表示,其中\(S\)的第\(i\)个字符是#则表示他在第\(i\)天工作,第\(i\)个字符是.表示他在第\(i\)天休息......