[BZOJ1922]大陆争霸-最短路略微扩展

本文详细解析了BZOJ1922题目的解题思路,通过维护两个数组来记录节点的到达时间和可进入时间,采用Dijkstra算法优化求解最短路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说在前面

写代码不够专注,然后某个2B的地方敲错了….查错半小时才过样例=A=


题目

BZOJ1922传送门

题意

(能力不足,实在是把这个题意概括不下来…放弃了)


解法

其实仔细想想就知道,只是在最短路上多维护一个信息而已。
维护dis1[i],dis2[i]两个数组,分别表示i点的到达时间和可进入时间。那么真实的进入时间就是max( dis1[i] , dis2[i] )
用dijkstra堆优化跑最短路。
对于每次从队列里取出的u,更新它能到的点的dis1和它所保护的点的dis2,并在更新dis2的时候把deg减1,一旦有点的deg为0,就入队(注意入队不能只在更新dis2的时候判断,如果一开始某个城市的庇护数就是0,那么它的dis2永远不会被更新,也就没法入队了。我的处理方法是每次更新完后直接for一遍所有的点。当然也可以写成在更新dis1和dis2的时候都判断入队)


自带大常数的代码

/**************************************************************
    Problem: 1922
    User: Izumihanako
    Language: C++
    Result: Accepted
    Time:756 ms
    Memory:6504 kb
****************************************************************/

#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std ;

int N , M , tp , head[3005] , deg[3005] ;
vector<int> pec[3005] ;
struct Path{
    int pre , to , len ;
}p[70005] ;
struct Data{
    int x ;
    long long dis ;
    Data(){};
    Data( int x_ , long long dis_ ) :x(x_) , dis(dis_){};
    bool operator < ( const Data &A ) const {
        return dis > A.dis ;
    }
};

void In( int t1 , int t2 , int t3 ){
    p[++tp].pre = head[t1] ;
    p[ head[t1] = tp ].to = t2 ;
    p[tp].len = t3 ;
}

bool vis[3005] ;
priority_queue<Data> q;
long long dis1[3005] , dis2[3005] ;
void solve(){
    for( int i = 1 ; i <= N ; i ++ )
        dis1[i] = 1LL<<60 , dis2[i] = 0 ;
    dis1[1] = dis2[1] = 0 ;
    q.push( Data( 1 , 0 ) ) ;
    while( !q.empty() ){
        Data u = q.top() ; q.pop() ;
        if( vis[u.x] ) continue ;
        vis[u.x] = true ;
        for( int i = head[u.x] ; i ; i = p[i].pre ){
            int v = p[i].to ;
            dis1[v] = min( dis1[v] , u.dis + p[i].len ) ;
        //  printf( "%d(%I64d) to %d(%I64d)  len = %d\n" , u.x , u.dis , v , dis1[v] , p[i].len ) ;
        }
        for( int i = 0 , siz = pec[u.x].size() ; i < siz ; i ++ ){
            int v = pec[u.x][i] ; deg[v] -- ;
            dis2[v] = max( dis2[v] , u.dis ) ;
        //  printf( "%d(%I64d) to %d(%I64d)\n" , u.x , u.dis , v , dis2[v] ) ;
        }
        for( int i = 1 ; i <= N ; i ++ )
            if( !vis[i] && deg[i] == 0 )
                q.push( Data( i , max( dis1[i] , dis2[i] ) ) ) ;
    }
    printf( "%lld" , max( dis1[N] , dis2[N] ) ) ;
}

int main(){
    scanf( "%d%d" , &N , &M ) ;
    for( int i = 1 , u , v , w ; i <= M ; i ++ ){
        scanf( "%d%d%d" , &u , &v , &w ) ;
        In( u , v , w ) ;
    }
    for( int i = 1 ; i <= N ; i ++ ){
        scanf( "%d" , &deg[i] ) ;
        for( int j = 1 , tmp ; j <= deg[i] ; j ++ ){
            scanf( "%d" , &tmp ) ;
            pec[tmp].push_back( i ) ;
        }
    }
    solve() ;
}
[menu_102] 70001=文件(&F) 40024=开始捕获(&S) 40025=停止捕获(&T) 40045=保存配置(&C) 40046=载入配置(&O) 40034=保存数据包数据到文件 40035=载入数据包数据文件 40039=导出 TCP/IP 流报告(&E) 40001=保存数据包摘要(&A) 40009=属性(&P) 40002=退出(&X) 70002=编辑(&E) 40031=复制(&C) 40007=全选(&A) 40015=全部取消选定(&D) 40032=下一项(&N) 40033=上一项(&P) 70003=查看(&V) 40005=显示网格线(&G) 40028=显示气球提示(&T) 40010=HTML 报告 - TCP/IP 流(&H) 40011=栏位设定(&N) 40012=自动调整栏的宽度(&A) 70004=选项(&O) 71001=显示模式(&M) 41101=自动(&A) 41102=ASCII(&S) 41103=16进制(&H) 71002=显示协议(&P) 41201=&TCP 41202=&UDP 41203=&ICMP 40027=显示 ASCII 码大于 127 的字符(&C) 40041=显示捕获时间(&T) 40042=将 IP 地址解析为主机名 40044=显示过滤设置 40040=高级选项(&A) 40043=捕获过滤设置 40026=选择设备(&O) 70005=帮助(&H) 40003=关于(&A) 41104=&URL 列表 [menu_104] 70001=Popup1 40010=生成 TCP/IP 流的 HTML 报告(&H) 40039=保存 TCP/IP 流报告(&E) 40001=保存数据包摘要(&A) 40011=栏位设定(&N) 40012=栏位自动宽度(&A) 40007=选择全部(&A) 40015=取消已选定(&D) 40031=复制(&C) 40032=下一项(&N) 40033=上一项(&P) 70002=Popup2 [dialog_105] caption=属性 1=确定 [dialog_108] caption=捕获选项 1007=原始套接字 (仅Windows 2000/XP) 1008=使用 WinPcap 包捕获驱动 1005=List1 1=确定 2=取消 1006=捕获方式 1009=选择网卡: 1045=选择网卡: [dialog_112] 1=确定 [dialog_113] caption=高级选项 1035=即时显示模式 - 捕获的同时列出 TCP/IP 会话 1011=每行字符数: 1013=显示时,在每 1025=显示 ASCII 字符 1026=在每行开头显示偏移量 1014=自动决定显示模式时要检查的字符数: 1032=不可显示的 ASCII 字符替换为: 1036=自动模式中, 若数据长度大于此限制则不显示16进制数据 1038=在下部面板中不显示数据长度大于此限制的项 1019=选择 1022=选择 1029=选择 1=确定 2=取消 1010=16进制显示选项 1015=个字符后插入额外的空格 1016=文字颜色 1017=源于本地主机的 TCP/IP 流的文字颜色: 1020=源于远程主机的 TCP/IP 流的文字颜色: 1030=捕获时间的文字颜色: 1031=常规显示选项 1034=捕获 1039=KB 1041=KB 1042=捕获同时显示 TCP/IP 会话内容开始的部分 1043=仅显示 TCP/IP 统计数据, 不在文件中保存捕获数据 1044=捕获时亦获取进程信息 1045=摘要模式 (每个连接之间不换行) [dialog_114] 1=确定 2=取消 3=清除 1037=输入一条或多条过滤规则, 以空格或回车分隔。以下是过滤字规则的几个子: [dialog_1096] caption=栏位设定 1003=上移(&U) 1004=下移(&D) 1006=显示(&S) 1007=隐藏(&H) 1008=默认 1=确定 2=取消 1000=钩选要显示的内容, 用上移或下移按钮排列显示顺序 1002=栏位宽度(像素): [strings] 4=%d 个 TCP/IP 会话 5=, 选定 %d 个 6=创建本文件使用的是 7=选择保存文件的名称 8=数据包摘要 9=无法启动选定网卡上的包捕获。 10=该项所含数据长度超过 %d KB 限制。 11=可使用导出选项将此项保存到文件中。 12=此 TCP/IP 会话太大,无法在捕获同时显示。 13=停止捕获后将显示会话的完整内容。 14=正在加载... %d 15=已捕获 %d 个数据包 16=错误: 无法创建数据包文件! 17=正在捕获... 18=选择用于保存已捕获数据的文件名 19=载入存有数据包数据的文件 20=确定要停止捕获并退出 SmartSniff 吗? 21=选择用于保存已捕获的数据包流的文件名称 22=数据包流报告 23=当前操作含有非常大的数据包流,载入过程可能很慢,要继续吗? 24=选择要保存的配置文件名 25=选择要载入的配置文件 51=捕获过滤选项 52=显示过滤选项 101=字节 501=文本文件 502=制表符分隔的文本文件 503=空格分隔的表格化文本文件 504=HTML 文件 - 水平方式 505=HTML 文件 - 垂直方式 506=XML 文件 521=ICMP 522=TCP 523=UDP 541=文本文件 542=HTML 文件 543=原始数据文件 601=SmartSniff 数据包文件 602=tcpdump/libpcap 文件 621=SmartSniff 配置文件 1001=编号 1002=协议 1003=本地地址 1004=远程地址 1005=本地端口 1006=远程端口 1007=数据包数量 1008=包含封装信息的总数据量 1009=捕获时间 1010=不含封装信息的数据量 1011=服务名称 1012=本地主机 1013=远程主机 1014=进程号 1015=进程文件名 1051=IP 地址 1052=设备名称
基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值