当前位置: 首页 > news >正文

UOJ#32【UR #2】跳蚤公路 题解

Preface

本文单独发表于博客园,借鉴了 yyb 学长 的题解。

感觉是个很牛的题!

Solution

深刻地感受到了最短路算法的多变性,而不是单纯地作为一个模板存在。

发现路径的长度可以表示为如下一次函数的形式:\(y=kx+b\)\(kx\) 表示经过的边给 \(x\) 乘上的系数,\(b\) 则表示经过的边的原本的权值之和(类似于普通最短路的 \(dist_x\))。

考虑对于 \(b\) 先进行处理,最后叠加 \(kx\) 的贡献。朴素的 Bellman-Ford 转移是尝试对于整张图松弛 \(n\) 轮,每次找到合适的边进行松弛,如果超过 \(n-1\) 轮仍然能够松弛说明存在负环。即 \(dp_{i,j}\) 表示经过 \(i\) 条边,\(1\to j\) 的最短路,则有 \(dp_{i,u}+w\to dp_{i+1,v}\)。那么将这道题进行一些小改动:\(dp_{i,j,k}\) 表示经过了 \(i\) 条边,经过的系数为 \(k\)\(1\to j\) 的最短路。那么实际上的路径长度为:\(dp_{i,j,k}+kx\)

负环条件也很好判断了:如果 \(\min\{dp_{n,i,j}+jx\}\geq \min\{dp_{n-1,i,k}+kx\}\) 则存在负环,因为此时仍然可以从 \(n-1\) 松弛到 \(n\)

那么解一下这个方程可以得到对于 \(i\) 来说的 \(x\) 构成负环的范围。求答案时对于每个点 \(i\),如果想要其不存在负环,那么所有可达 \(i\) 的点 \(j\) 都不能有负环,所以对于所有 \(1\to j \to i\) 的点集 \(j\),求 \(j\) 构成负环的区间的并集,则 \(1\to i\) 不存在负环的集合为该并集的补集。

具体实现细节很多啊。调的挺破防的。

Code

#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
const int N=105,MAX=102,inf=1e18;
int n,m,dp[N][N][N<<2],f[N][N];
struct node{int u,v,val,typ;}e[N*N];
vector<pii>g[N],now;
signed main(){cin>>n>>m;for(int i=1,x,y,z,w;i<=m;i++){cin>>x>>y>>z>>w,f[x][y]=1;e[i]={x,y,z,w};}for(int i=1;i<=n;i++)f[i][i]=1;for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]|=f[i][k]&f[k][j];for(int i=0;i<=n;++i)for(int j=1;j<=n;++j)for(int k=-n;k<=n;++k)dp[i][j][k+MAX]=inf;dp[0][1][MAX]=0;for(int i=1;i<=n;i++){memcpy(dp[i],dp[i-1],sizeof(dp[i]));for(int j=1;j<=m;j++){int u=e[j].u,v=e[j].v,val=e[j].val,typ=e[j].typ;for(int k=-n;k<=n;k++)if(dp[i-1][u][k+MAX]!=inf)dp[i][v][k+MAX+typ]=min(dp[i][v][k+MAX+typ],dp[i-1][u][k+MAX]+val);}}for(int i=1;i<=n;i++){for(int j=-n;j<=n;j++){if(dp[n][i][j+MAX]>=inf)continue;int L=-inf,R=inf,flg=0;for(int k=-n;k<=n;k++){if(dp[n-1][i][k+MAX]>=inf)continue;if(j>k)R=min(R,(int)ceil(1.0*(dp[n-1][i][k+MAX]-dp[n][i][j+MAX])/(j-k)));else if(j<k)L=max(L,(int)floor(1.0*(dp[n-1][i][k+MAX]-dp[n][i][j+MAX])/(j-k)));else if(dp[n][i][j+MAX]>=dp[n-1][i][k+MAX]){flg=1;break;}}if(!flg&&L<R)g[i].push_back({L,R});}}for(int i=1;i<=n;i++){now.clear();for(int j=1;j<=n;j++)if(f[1][j]&&f[j][i])for(auto it:g[j])now.push_back(it);sort(now.begin(),now.end());int L=inf,R=-inf,lst=-inf,flg=0;for(int j=0;j<now.size();j++){if(!j&&now[j].fi>-inf){L=-inf,R=now[j].fi,flg=1;break;}if(lst!=-inf&&lst<=now[j].fi){L=lst,R=now[j].fi,flg=1;break;}lst=max(lst,now[j].se);} if(!flg&&lst<inf)L=lst,R=inf;if(now.empty()||L==-inf||R==inf)cout<<"-1\n";else cout<<max(0ll,R-L+1)<<"\n";}return 0;
}
http://www.hskmm.com/?act=detail&tid=21547

相关文章:

  • 2025 年窗帘杆源头厂家最新推荐榜单:包含支架 / 环 / 全自动 / 可伸缩等多类产品及配件,帮助选到品质与交期双优的优质厂家
  • 2025 年电动窗帘厂家推荐榜单:聚焦国内优质企业定制实力与口碑,为采购者提供最新选择参考电动窗帘系统/电机/轨道/配件/智能电动窗帘厂家推荐
  • Vue3 使用注意事项
  • ClickHouse ReplacingMergeTree 去重陷阱:为什么你的 FINAL 查询无效? - 若
  • js中?? 和 || 的区别详解
  • 微信机器人API接口| 个人开发者必备
  • 直击现场! “ 直通乌镇 ”开源赛复赛收官,OpenCSG担任评委,十强藏着哪些产业机会?
  • Python 列表生成式、字典生成式与生成器表达式
  • java 解析json字符串,获取特定的字段值,JsonObject
  • python 批量提取txt数据中的值写入csv
  • 回忆中学的函数
  • Java 一行一行的读取文本,小Demo 大学问
  • 家里wifi电信出口ip如何控制不变,解决访问云服务器上面的资源
  • 2025 年挤压造粒机源头厂家最新推荐榜单:前五企业技术实力、服务能力及口碑测评指南对辊挤压/化肥挤压/干粉挤压造粒机厂家推荐
  • MYSQL数据库取消表的约束
  • 2025 年京东 e 卡回收平台最新推荐排行榜:权威测评实时结算平台,助力用户安全高效转让京东 e 卡
  • 2025 年支付宝消费券回收平台最新推荐榜单:优质平台权威测评,助您高效安全处理闲置消费券支付宝消费券回收/闲置支付宝消费券回收/支付宝消费券快速回收平台推荐
  • ICP备案查询网站 域名备案查询
  • 2025 年注浆管厂家最新权威推荐排行榜:聚焦 R780/108 / 隧道 / 预埋 / 桩基等专用产品,精选 TOP5 优质企业
  • stable diffusion网络结构详解
  • 9.30
  • 网络与系统攻防技术实验一——逆向破解与Bof
  • 【python】解决grpcio.protoc生成的pb文件里面没有类和方法定义
  • 阙韩
  • “计算机配置\Windows 设置\安全设置\本地策略\审核策略” 配置后不生效
  • Spring Boot 事件发布与监听 观察者模式的实际应用 - 实践
  • P13969 [VKOSHP 2024] Exchange and Deletion
  • Matlab 通用库的fft和dsp toolbox的dsp.fft对比
  • [CTS2024] 众生之门
  • [CEOI 2025] Equal Mex