洛谷 P6573 [BalticOI 2017] Toll 题解
算是回归OI后第一道自己写的题(考CSP的时候可没回归)
写篇题解纪念一下
题目大意: \(n\) 个点,\(m\) 条单向边,每条边的两端点 \(x\),\(y\)必定满足 \(\left\lfloor\dfrac{y}{k}\right\rfloor=\left\lfloor\dfrac{x}{k}\right\rfloor+1\), \(q\)次询问,求每一对\(a\),\(b\)的最短距离。
\(n<=5*10^{4},q<=10^4\)\(1<k<5\),保证\(a\)<\(b\)
简单分析一下容易发现这是个分层图,每 \(k\) 个点为一层,只有相邻的层间有边且边只能往编号大的方向去。
然后就是考虑这个东西怎么维护了,考虑前两天CSP2022的T4做法之一,矩阵乘法+倍增优化dp
容易发现我们可以把每个层缩成一个点,之后的图就成了好多条链(注意不一定保证联通)
然后对于这条链中的每两个相邻节点(即相邻两层),我们可以用类似Floyd的方法把原图中的边构造一个矩阵,接着就可以矩阵乘法快速合并了。
然后再倍增处理一下就结束了
记得判连通性。
(我自己的实现把链当成树了所以看起来有些麻烦。。。但是问题不大,能过就行)
点击查看代码
#include <bits/stdc++.h>
#define N 50010
#define M 1000010
#define pii pair<int,int>
#define mkp make_pair
#define pb push_back
#define fi first
#define se second
//#define int long long
//#define MOD
#define INF 1000000000
#define int_edge int to[M],nxt[M],head[N],cnt=0;
using namespace std;
int k,n,m,q,fa[N][16],f[N],dep[N],eid=0,vis[N];
int_edge;void add_edge(int x,int y ){to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;}
map<pii,int>mp;
struct Y{int x,y,t;};vector<Y>E[N];
int id(int x){return x/k+1;}
//int_edge;int val[M];void add_edge(int x,int y,int z){to[++cnt]=y;val[cnt]=z;nxt[cnt]=head[x];head[x]=cnt;}
struct Matrix{
int a[5][5];
Matrix(){memset(a,0x3f,sizeof(a));}
Matrix operator * (const Matrix &y){
Matrix sum;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
for(int k=0;k<5;k++)
sum.a[i][j]=min(sum.a[i][j],a[i][k]+y.a[k][j]);
return sum;
}
}dn[N][16];
Matrix init(){
Matrix x;for(int i=0;i<k;i++)x.a[i][i]=0;return x;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void dfs(int nw,int lst){
vis[nw]=1;
fa[nw][0]=lst;dep[nw]=dep[lst]+1;
if(lst!=0){
for(auto e:E[mp[mkp(lst,nw)]]){
dn[nw][0].a[e.x%k][e.y%k]=e.t;
}
}
for(int i=1;i<=15;i++){
fa[nw][i]=fa[fa[nw][i-1]][i-1];
dn[nw][i]=dn[fa[nw][i-1]][i-1]*dn[nw][i-1];
}
for(int i=head[nw];i;i=nxt[i])
if(to[i]!=lst)dfs(to[i],nw);
}
signed main()
{
scanf("%d %d %d %d",&k,&n,&m,&q);
for(int i=0;i<n;i++)f[i]=i;
for(int i=1,x,y,t;i<=m;i++){
scanf("%d %d %d",&x,&y,&t);
f[find(x)]=find(y);
if(mp.find(mkp(id(x),id(y)))==mp.end()){
mp[mkp(id(x),id(y))]=++eid;
add_edge(id(x),id(y));
}
E[mp[mkp(id(x),id(y))]].pb(Y{x,y,t});
}
for(int i=1;i<=id(n);i++)if(!vis[i])dfs(i,0);
while(q--){
int x,y;scanf("%d %d",&x,&y);
if(find(x)!=find(y)){puts("-1");continue;}
int id1=id(x),id2=id(y);
Matrix ans=init();
for(int i=15;i>=0;i--)
if(dep[fa[id2][i]]>=dep[id1])
ans=dn[id2][i]*ans,id2=fa[id2][i];
if(ans.a[x%k][y%k]==1061109567)puts("-1");
else printf("%d\n",ans.a[x%k][y%k]);
}
return 0;
}
洛谷 P6573 [BalticOI 2017] Toll 题解的更多相关文章
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
- 洛谷P4047 [JSOI2010]部落划分题解
洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...
- 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)
洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...
- 洛谷 P4665 [BalticOI 2015]Network
洛谷 P4665 [BalticOI 2015]Network 你有一棵 $ n $ 个节点的树,你可以在树上加一些边,使这棵树变成一张无重边.自环的图,且删掉任意一条边它仍然联通.求最少要加多少条边 ...
- 洛谷 P3951 NOIP 2017 小凯的疑惑
洛谷 P3951 NOIP 2017 小凯的疑惑 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付 ...
- 洛谷10月月赛II题解
[咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...
- [洛谷P1823]音乐会的等待 题解(单调栈)
[洛谷P1823]音乐会的等待 Description N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没 ...
- BZOJ2527 & 洛谷3527:[Poi2011]Meteors——题解
+++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...
- 洛谷 p1516 青蛙的约会 题解
dalao们真是太强了,吊打我无名蒟蒻 我连题解都看不懂,在此篇题解中,我尽量用语言描述,不用公式推导(dalao喜欢看公式的话绕道,这篇题解留给像我一样弱的) 进入正题 如果不会扩展欧里几德的话请先 ...
随机推荐
- 聊天机器人框架Rasa资源整理
Rasa是一个主流的构建对话机器人的开源框架,它的优点是几乎覆盖了对话系统的所有功能,并且每个模块都有很好的可扩展性.参考文献收集了一些Rasa相关的开源项目和优质文章. 一.Rasa介绍 1.R ...
- ARC122D XOR Game(博弈论?字典树,贪心)
题面 ARC122D XOR Game 黑板上有 2 N 2N 2N 个数,第 i i i 个数为 A i A_i Ai. O I D \rm OID OID(OneInDark) 和 H I D ...
- 在 C# CLR 中学习 C++ 之了解 namespace
一:背景 相信大家在分析 dump 时,经常会看到 WKS 和 SRV 这样的字眼,如下代码所示: 00007ffa`778a07b8 coreclr!WKS::gc_heap::segment_st ...
- nginx的安装和配置
目录 目录 一.购买下载SSL证书 二.修改Nginx配置信息 三.重启Nginx 一.购买下载SSL证书 SSL证书阿里云做活动期间可以免费申请,购买SSL证书时选择单域名-DV SSL-免费版即可 ...
- std::atomic和std::mutex区别
std::atomic介绍 模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.在多线程调用下,利用std::atomic可实 ...
- Windows平台Unity3d播放多路RTMP或RTSP流
好多开发者在做AR.VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大.而且周期长,不适合快速出产 ...
- C#实现HTTP访问类HttpHelper
在项目开发过程中,我们经常会访问第三方接口,如我们需要接入的第三方接口是Web API,这时候我们就需要使用HttpHelper调用远程接口了.示例中的HttpHelper类使用Log4Net记录了每 ...
- 新增 Oracle 兼容函数-V8R6C4B0021
KingbaseES V8R6C4B0021新增加以下Oracle 兼容函数. 一.bin_to_num Oracle bin_to_num 函数用于将二进制位转换成十进制的数. 1.传入参数 tes ...
- KingbaseES启动数据库失败后如何分析
关键字: KingbaseES.sys_ctl.启动日志 一.KingbaseES数据库服务启动 1.1 数据库启动机制 1) 数据库通过sys_ctl工具手工启动数据库服务kingbase. 2) ...
- 如何使用helm优雅安装prometheus-operator,并监控k8s集群微服务
前言:随着云原生概念盛行,对于容器.服务.节点以及集群的监控变得越来越重要.Prometheus 作为 Kubernetes 监控的事实标准,有着强大的功能和良好的生态.但是它不支持分布式,不支持数据 ...