Codeforces 576D - Flights for Regular Customers(bitset 优化广义矩阵乘法)
题意:
有一张 \(n\) 个点 \(m\) 条边的有向图,你初始在 \(1\) 号点,边上有边权 \(c_i\) 表示只有当你经过至少 \(c_i\) 条边的时候你才能经过第 \(i\) 条边。
求从 \(1\) 号点开始最少走过多少条边才能到达 \(n\) 号点。
\(n,m \leq 150,c_i\leq 10^9\)
注意到题目中 \(c_i\) 的数据范围可以达到 \(10^9\),我们显然不能一步步枚举可达的位置。
但是 \(m\) 的数据范围很小,说明转移矩阵最多改变 \(150\) 次,这启示我们可以用矩阵乘法
具体来说,我们建立 \(1\times n\) 的矩阵 \(A\),\(A_i\) 表示在当前状态下 \(i\) 是否能够到达(\(0/1\))。
再建立一个 \(n\times n\) 的转移矩阵 \(B\),\(B_{i,j}\) 表示 \(i\) 与 \(j\) 是否有边相连。
那么走一步之后,新的 \(A'_i=\or_{i=1}^nA_k\and B_{k,i}\)
也就是说,如果存在一个点 \(k\) 使得在当前状态下能够到达 \(k\) 并且 \(k\) 与 \(i\) 有直接边相连,那么就可以从 \(k\) 走到 \(i\)。
由于广义矩阵乘法也满足乘法结合律,那么走 \(t\) 步后可达状态为 \(A\times B^t\)
考虑将边按照 \(c_i\) 从小到大排序,然后依次改变转移矩阵 \(B\)。
然后做一遍多源 \(bfs\),求出可达的所有点中,到达点 \(n\) 的最短距离。
时间复杂度 \(\mathcal O(n^3m\log c_i)\)。注意到矩阵 \(A,B\) 每一位都是 \(0\) 或 \(1\),矩阵乘法中也只包含位运算,因此可以使用 bitset 优化,时间复杂度 \(\mathcal O(\frac{n^3m\log c_i}{\omega})\) 。
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
const int MAXN=150+5;
const int MAXM=150+5;
int n,m,d[MAXN];
struct edge{
int u,v,c;
friend bool operator <(edge a,edge b){
return a.c<b.c;
}
} e[MAXM];
struct mat{
bitset<MAXN> x[MAXN];
friend mat operator *(mat a,mat b){
mat c;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
if(a.x[i][j]) c.x[i]|=b.x[j];//optimize multiplation by bitset
return c;
}
} to,c;
mat qpow(mat x,int e){
mat ret;for(int i=1;i<=n;i++) ret.x[i][i]=1;
while(e){if(e&1) ret=ret*x;x=x*x;e>>=1;}return ret;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);
sort(e+1,e+m+1);to.x[1][1]=1;int pre=0,ans=2e9;
for(int i=1;i<=m;i++){
to=to*qpow(c,e[i].c-pre);
pre=e[i].c;c.x[e[i].u][e[i].v]=1;
memset(d,63,sizeof(d));
queue<int> q;for(int j=1;j<=n;j++) if(to.x[1][j]) q.push(j),d[j]=0;
while(!q.empty()){
int cur=q.front();q.pop();
for(int j=1;j<=n;j++) if(c.x[cur][j]&&d[j]>1e9){
d[j]=d[cur]+1;q.push(j);
}
}
if(d[n]<1e9) ans=min(ans,e[i].c+d[n]);
}
if(ans==2e9) puts("Impossible");
else printf("%d\n",ans);
return 0;
}
Codeforces 576D - Flights for Regular Customers(bitset 优化广义矩阵乘法)的更多相关文章
- Codeforces 576D Flights for Regular Customers(矩阵加速DP)
题目链接 Flights for Regular Customers 首先按照$d$的大小升序排序 然后分成$m$个时刻,每条路径一次处理过来. $can[i][j]$表示当前时刻$i$能否走到$j ...
- Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)
题目链接 http://codeforces.com/contest/576/problem/D 题解 把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\ ...
- Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)
这破题调了我一天...错了一大堆细节T T 首先显然可以将边权先排序,然后逐个加进图中. 加进图后,倍增跑跑看能不能到达n,不能的话加新的边继续跑. 倍增的时候要预处理出h[i]表示转移矩阵的2^0~ ...
- Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP
题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...
- (中等) CF 576D Flights for Regular Customers (#319 Div1 D题),矩阵快速幂。
In the country there are exactly n cities numbered with positive integers from 1 to n. In each city ...
- 576D Flights for Regular Customers
分析 https://www.cnblogs.com/onioncyc/p/8037056.html 写的好像有点问题 但是大致就是这个意思 代码很好理解 代码 #include<bits/st ...
- CF576D Flights for Regular Customers 矩阵乘法 + Bitset优化
%%%cxhscst2's blog Codeforces 576D Flights for Regular Customers(矩阵加速DP) 代码非常优美 + 简洁,学习到了 Code: #inc ...
- 【CodeForces】576 D. Flights for Regular Customers
[题目]D. Flights for Regular Customers [题意]给定n个点m条边的有向图,每条边有di表示在经过该边前必须先经过di条边,边可重复经过,求1到n的最小经过边数.n,m ...
- 「CF576D」 Flights for Regular Customers
「CF576D」 Flights for Regular Customers 对不起我又想网络流去了 你看这长得多像啊,走过至少多少条边就是流量下界,然后没上界 但是这个题求的最少走多少条边啊...完 ...
随机推荐
- Golang通脉之数据类型
标识符与关键字 在了解数据类型之前,先了解一下go的标识符和关键字 标识符 在编程语言中标识符就是定义的具有某种意义的词,比如变量名.常量名.函数名等等. Go语言中标识符允许由字母数字和_(下划线) ...
- Bug概述、状态、类型、级别、优先级提交和Bug生命周期管理
缺陷概述: 1)缺陷(Defect):是指存在于软件之中偏差,可被激活,以静态形式存在于软件内部,相当于Bug. 2)故障(Fault):当缺陷被激活后,软件运⾏中出现的状态,可引起意外情况,若不加处 ...
- 【UE4 C++ 基础知识】<3> 基本数据类型、字符串处理及转换
基本数据类型 TCHAR TCHAR就是UE4通过对char和wchar_t的封装 char ANSI编码 wchar_t 宽字符的Unicode编码 使用 TEXT() 宏包裹作为字面值 TCHAR ...
- 23.合并k个有序链表
合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1-&g ...
- UltraSoft - Alpha - Scrum Meeting 1
Date: Apr 06th, 2020. 会议内容为讨论功能规格书和技术规格书的撰写. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM.后端 进行Djan ...
- hdu 5093 Battle ships(二分图最大匹配)
题意: M*N的矩阵,每个格子上是三个之一:*.o.#. (1 <= m, n <= 50) *:海洋,战船可以停在上面. o:浮冰,战船 ...
- 测试平台系列(72) 了解ApScheduler基本用法
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们调研了一下市面上 ...
- 在线编辑Word——插入图表
在Word中可插入图表,配合使用表格能够更加全方位的展示数据的可信度并增加数据的可读性.本文将通过使用在线编辑器 Spire.Cloud Word 演示如何来插入图表,并设置相关格式化操作.具体步骤如 ...
- Firefox火狐浏览器提示您的链接并不安全(解决办法)
火狐浏览器不管访问什么,一直提示连接不安全 解决办法: 1.在Firefox地址栏输入"about:config",回车,进入如下图页面 点击"我了解此风险" ...
- win10各版本激活码
win + x进入Power shell(管理员),依次输入 Win10专业版 slmgr.vbs /upk slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX slmg ...