【学习笔记】CF576D Flights for Regular Customers

这篇具有很好参考价值的文章主要介绍了【学习笔记】CF576D Flights for Regular Customers。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

不同于传统的最短路,当我们走到一个节点的时候,还要记录此时经过的边数才能完成转移。但是第二维太大了,太抽象了!

看到 m m m这么小,很难不想到离散化。那么设 f i , j f_{i,j} fi,j表示当第 i i i条边出现时,在节点 j j j是否可行,注意这是 01 01 01状态。转移非常粗暴,因为我们要在当前的边集下逗留 d i + 1 − d i d_{i+1}-d_i di+1di步,所以直接每次跳 2 i 2^i 2i步即可。

算一下复杂度,居然是 n 3 m log ⁡ V n^3m\log V n3mlogV,因为每加入一条边都要跑一遍 Floyd \text{Floyd} Floyd,太抽象了!!因为是 01 01 01状态所以可以用 bitset \text{bitset} bitset优化,这样复杂度 n 3 w m log ⁡ V \frac{n^3}{w}m\log V wn3mlogV,这样算下来已经可以通过了。。。

发现问题瓶颈在于计算邻接矩阵的 k k k次幂上面,可以采取动态加边的思想来维护,然后因为左乘的是一个向量(哪些点可达),所以这一部分也可以少一个 n n n。这样复杂度 n 2 w m log ⁡ V \frac{n^2}{w}m\log V wn2mlogV。但是为什么没有人写这个做法呢?文章来源地址https://www.toymoban.com/news/detail-531199.html

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=155;
int n,m,res=0x3f3f3f3f,dis[N];
queue<int>Q;
struct node{
    bitset<N>f[N];
    node(){for(int i=1;i<=n;i++)f[i].reset();}
    node operator *(const node &a)const{
        node r;
        for(int i=1;i<=n;i++)assert(r.f[i].count()==0);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(f[i][j]){
                    r.f[i]|=a.f[j];
                }
            }
        }
        return r;
    }
}f,mat;
struct edge{
    int x,y,d;
    bool operator <(const edge &a)const{
        return d<a.d;
    }
}edges[N];
bitset<N>arrays;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;for(int i=1;i<=m;i++)cin>>edges[i].x>>edges[i].y>>edges[i].d;
    sort(edges+1,edges+1+m);
    arrays[1]=1;
    for(int i=1;i<=m;i++){
        int x=edges[i].x,y=edges[i].y,k=edges[i].d-edges[i-1].d;
        f=mat;
        for(;k;k>>=1){
            if(k&1){
                bitset<N>tmp;
                for(int j=1;j<=n;j++){
                    for(int k=1;k<=n;k++){
                        if(f.f[j][k]&&arrays[j])tmp[k]=1;
                    }
                }
                arrays=tmp;
            }
            f=f*f;
        }
        mat.f[x][y]=1;
        memset(dis,0x3f,sizeof dis);
        for(int j=1;j<=n;j++){
            if(arrays[j]){
                Q.push(j),dis[j]=edges[i].d;
            }
        }
        while(Q.size()){
            int u=Q.front();Q.pop();
            for(int v=1;v<=n;v++){
                if(mat.f[u][v]&&dis[u]+1<dis[v]){
                    dis[v]=dis[u]+1;
                    Q.push(v);
                }
            }
        }
        res=min(res,dis[n]);
    }
    if(res==0x3f3f3f3f)cout<<"Impossible";
    else cout<<res;
}

到了这里,关于【学习笔记】CF576D Flights for Regular Customers的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【学习笔记】CF573E Bear and Bowling

    感觉贪心的做法比较自然🤔,推荐 这篇博客 非常经典 牛逼 的贪心思路: 考虑每次加入一个数,位置 i i i 的贡献为 V i = k i × a i + b i V_i=k_itimes a_i+b_i V i ​ = k i ​ × a i ​ + b i ​ ,其中 k i k_i k i ​ 表示 i i i 以前被选的位置的个数, b i b_i b i ​ 表示 i i i 以后被选的数的

    2024年02月07日
    浏览(24)
  • 【学习笔记】CF1783G Weighed Tree Radius

    如果 w v ( u ) w_v(u) w v ​ ( u ) 指代的就是直径,或者说我们再添一项 a v a_v a v ​ ,那么我们几乎就做完了。 于是自然而然想到换一个定义: d ( u , v ) = dist ( u , v ) + a u + a v d(u,v)=text{dist}(u,v)+a_u+a_v d ( u , v ) = dist ( u , v ) + a u ​ + a v ​ 。 发现这样转化过后,设直径的两个端点

    2024年02月16日
    浏览(11)
  • 【学习笔记】CF1835D Doctor‘s Brown Hypothesis

    有点难😅 发现 x , y x,y x , y 在一个强连通块内,这样一定有环🤔 发现可以找到强连通块内所有环长度的 gcd ⁡ gcd g cd ,这样从 x x x 到 y y y 的所有路径的长度都模这个数同余,又因为 K K K 非常大,所以我们总可以遍历整个强连通块并走若干个环,因此只需要从 x x x 到 y y

    2024年02月09日
    浏览(16)
  • 【学习笔记】CF582D Number of Binominal Coefficients

    注意 P P P 事实上不会影响复杂度,因为关于组合数,我们有一个非常经典的结论: ( n + m m ) binom{n+m}{m} ( m n + m ​ ) 包含的 P P P 的幂的次数等于 n n n 和 m m m 在 P P P 进制下做加法的进位次数。这样,我们只需要关心进位的次数,而不必知道每一位具体是多少。 这个结论的证

    2024年02月12日
    浏览(10)
  • Kendo UI for Angular 学习笔记

    [ maxlength ]:最大输入长度 [showSuccessIcon] / [showErrorIcon]:  显示内置验证图标 kendoTextBoxPrefixTemplate:前 后缀 icon [ clearButton ]=\\\"true\\\" : TextBox 中呈现 Clear 按钮 (“X”) [( ngModel )]=\\\"value变量\\\"  :双向绑定  [ disabled ]=\\\"isDisabled\\\" :禁用组件,isDisabled 变量值为布尔值  [ readonly ]=\\\"true

    2024年02月02日
    浏览(14)
  • Python学习笔记:List、Tuple、for循环

    Python学习笔记:List、Tuple、for循环

    1.list   2.matrix 其实就是list嵌套,可以使用双重for遍历,所包含方法与list一致 3.for循环实例:随机生成一个固定大小的list,并找到list中最大的数和对应的index 4.for循环实例:删除list中重复的元素  5.tuple tuple不可变,但是可以多个tuple拼接组合 6.dictionary {key:value}  7.dictionary

    2024年02月14日
    浏览(7)
  • Linux shell编程学习笔记17:for循环语句

    Linux shell编程学习笔记17:for循环语句

    Linux Shell 脚本编程和其他编程语言一样,支持算数、关系、布尔、字符串、文件测试等多种运算,同样也需要进行根据条件进行流程控制,提供了if、for、while、until等语句。  之前我们探讨了if语句,现在我们来探讨for循环语句。 Linux Shell中的for语句十分灵活,格式多样,我

    2024年02月06日
    浏览(12)
  • 【Dynamo学习笔记】Dynamo for Revit建模基础

    【Dynamo学习笔记】Dynamo for Revit建模基础

    参考资料: (1) 罗嘉祥,宋姗,田宏钧. 《Autodesk Revit炼金术——Dynamo基础实战教程》,同济大学出版社 (2)【Dynamo学习笔记】基础入门 为了能和Revit进行交互,Dynamo中内置了很多Revit的节点,包含一系列用于选择、创建、编辑、查询等操作,帮助用户简化建模的过程,提

    2024年01月18日
    浏览(10)
  • 【李宏毅机器学习·学习笔记】Tips for Training: Adaptive Learning Rate

    【李宏毅机器学习·学习笔记】Tips for Training: Adaptive Learning Rate

    本节课主要介绍了Adaptive Learning Rate的基本思想和方法。通过使用Adaptive Learning Rate的策略,在训练深度神经网络时程序能实现在不同参数、不同iteration中,学习率不同。 本节课涉及到的 算法或策略 有:Adgrad、RMSProp、Adam、Learning Rate Decay、Warm Up。 本节课 参考的资料 有: MI

    2024年02月14日
    浏览(13)
  • VUE3 学习笔记(八)引入 EasyUI for Vue

    VUE3 学习笔记(八)引入 EasyUI for Vue

      目录 一、什么是 EasyUI? 二、安装EasyUI for Vue3 1. 使用NPM安装 2. 导入EasyUI 三、安装完成出现问题解决 easyui是一个基于jQuery、Angular、Vue和React的用户界面组件的集合。 easyui为构建现代的、交互式的、javascript应用程序提供了基本功能。 使用easyui,你不需要写很多javascript代码,

    2023年04月21日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包