Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)
这破题调了我一天...错了一大堆细节T T
首先显然可以将边权先排序,然后逐个加进图中。
加进图后,倍增跑跑看能不能到达n,不能的话加新的边继续跑。
倍增的时候要预处理出h[i]表示转移矩阵的2^0~i的或和,转移是h[i]=h[i-1]*h[i-1]。
注意两个矩阵包含0~i和0~j相乘的时候,得到的矩阵是0~i*j的,而两个矩阵包含0~i和0~j或起来的时候,得到的矩阵是j~i+j的。
倍增的时候因为必须答案单调,所以当前的值必须或上之前的值。
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<bitset> #include<algorithm> #include<cmath> using namespace std; const int maxn=160, inf=1e9+160; struct mtx{bitset<maxn>mp[maxn]; mtx(){for(int i=0;i<maxn;i++) mp[i].reset();}}tmp, tmp2, f, base, h[35]; struct poi{int x, y, dis;}a[maxn]; int n, m; mtx operator *(mtx a, mtx b) {mtx c;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(a.mp[i][j]) c.mp[i]|=b.mp[j];return c; } mtx operator |(mtx a, mtx b) {mtx c; for(int i=1;i<=n;i++)c.mp[i]|=a.mp[i]|b.mp[i];return c; } inline void power(int b) {if(b<=0) return;for(;b;b>>=1, tmp=tmp*tmp)if(b&1) f=f*tmp; } inline bool cmp(poi a, poi b){return a.dis<b.dis;} int main() {scanf("%d%d", &n, &m);for(int i=1;i<=m;i++) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].dis);sort(a+1, a+1+m, cmp); a[m+1].dis=inf;if(a[1].dis) return puts("Impossible"), 0;for(int i=1;i<=n;i++) f.mp[i][i]=1;for(int i=1;i<=m;i++){tmp=base; power(a[i].dis-a[i-1].dis);base.mp[a[i].x][a[i].y]=1;int up=log2(a[i+1].dis-a[i].dis);h[0]=base; for(int j=1;j<=n;j++) h[0].mp[j][j]=h[0].mp[j][j]|1;mtx tmpx; for(int j=1;j<=n;j++) tmpx.mp[j][j]=1;if(a[i+1].dis-a[i].dis & 1) tmpx=tmpx|(tmpx*h[0]);for(int j=1;j<=up;j++) {h[j]=h[j-1]*h[j-1];if(a[i+1].dis-a[i].dis & (1<<j)) tmpx=tmpx|(tmpx*h[j]);}tmpx=f*tmpx; if(!tmpx.mp[1][n]) continue;mtx tmp1=f; int ans=0;for(int j=up;j>=0;j--)if(a[i].dis+ans+(1<<j)<=a[i+1].dis){tmp2=tmp1; tmp2=tmp2*h[j];if(tmp2.mp[1][n]) continue;ans+=(1<<j); tmp1=tmp2;}return printf("%d\n", a[i].dis+ans+1), 0;}puts("Impossible"); }
View Code
转载于:https://www.cnblogs.com/Sakits/p/8040256.html
Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)相关推荐
- Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)
题目链接 http://codeforces.com/contest/576/problem/D 题解 把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\ ...
- BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)
题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...
- bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑(倍增floyd)
1706: [usaco2007 Nov]relays 奶牛接力跑 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 675 Solved: 352 [S ...
- BZOJ 2085 [Poi2010]Hamsters Hash+倍增floyd
题意:链接 方法: Hash+倍增floyd 解析: 首先这个BZ的无脑翻译我真是受不了. 加俩条件 所有串的长度总和不超过100000,并且对于任意不同子串A,B,A不包含于B,B不包含于A. 然后 ...
- BZOJ 2085 Poi2010 Hamsters Hash+倍增Floyd
题目大意:给定n个长度总和不超过10W的字符串,求一个最短的母串,使所有字符串的出现次数之和=m 这n个字符串保证不互相包含 TM能不能好好翻译了 令f[i][j]表示第i个字符串后面接上第j个字符串 ...
- CodeForces #549 Div.2 ELynyrd Skynyrd 倍增算法
题目 这道题目实际上可以用动态规划来做. 对于每个区间,我们从右边边界,往左边走,如果能走n-1次,那说明以右边边界为起点存在一个题目中说的子链. 利用倍增算法,实际上倍增也是动态规划.f[i][j] ...
- 【bzoj2360】【cstc2011】【幸福路径】【倍增+floyd】
Description 有向图 G有n个顶点 1, 2, -, n,点i 的权值为 w(i).现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条 边 ...
- [Hash 倍增Floyd] BZOJ 2085 [Poi2010]Hamsters
Po姐的题解:http://blog.csdn.net/popoqqq/article/details/44077515 搬运下复杂度分析吧 这不会T? 首先设第i个字符串的长度为ai,设k=Σai ...
- Codeforces Gym101246C:Explode 'Em All(DP + bitset)
http://codeforces.com/gym/101246/problem/C 题意:给出一个n*m的图,"*"表示这个地方需要炸掉,炸弹可以如果丢在(i,j)位置的话,那么 ...
最新文章
- js小效果-简易计算器
- Flex开发实战(一)--Flex的详细介绍
- iOS ALAsset的选取和存储
- 【Kotlin】IntelliJ IDEA 创建 Kotlin 项目
- 推动网络由连接为中心向用户为中心转变
- boost::quick_exit相关的测试程序
- Linux_CentOS-服务器搭建 六
- 剑指0ffer04.二维数组中的查找
- 《深入学习 Golang》并发编程
- copy-and-swap idiom详解和实现安全自我赋值
- JavaScript:继承详解
- win32汇编--创建窗口程序(RadAsm)
- STM32cubemx教程及STM32入门(四)串口通信
- Excel表格数据的下载
- 国内6大常见免费数据采集器特点分析
- 加密文档的三种基本方法
- NVIDIA英伟达又发布了哪些黑科技?
- Java航班预订统计leetcode_1109
- 【漏洞通告】Gitlab存在多个高危漏洞
- 学堂在线-清华大学-操作系统实验Lab1【练习3-4】