n<=150个点,m<=150条路,每条路Ai,Bi,Di表示Ai到Bi有一条有向边,使用他前至少要走Di条路,问1到n最少走几条路。

又是n^4过150的题。。。。

不同于传统的最短路,这次的最短路包括了m个图,并且状态和走的路径数有关。所以要一个状态Can(i,j)表示能否到达点i走j步。

由于有m个图,我们就一个一个图来看。把边从小到大加入图,每加入某个值的一组边即可构成一个新图。在进入一个新图之前,我需要知道:在上个图的最后一步,从1走能走到哪些点,已这些点为起点进行下一步的探索。新来一个图之后,先尝试在这个图上走 不进入下个图的边数,能不能走到n点,如果能输出答案,不能就记这个图最后能从一到达哪些点然后进行下一步扩展。而尝试找能否走到n点,不可能从C(i,Dj)一路推到C(i,Dj+1)这里的D排序好了,所以需要一个倍增floyd。

然而这样的话是m*n*n*n*logMax,咋整?floyd用bitset优化!m*n*n*n*logMax/32大概就是n^4啦

  1. #include<stdio.h>
  2. #include<algorithm>
  3. #include<string.h>
  4. #include<stdlib.h>
  5. #include<bitset>
  6. //#include<math.h>
  7. //#include<iostream>
  8. using namespace std;
  9.  
  10. int n,m;
  11. #define maxn 161
  12. struct Mat
  13. {
  14. bitset<maxn> a[maxn];
  15. void clear() {for (int i=;i<=n;i++) a[i].reset();}
  16. Mat operator * (const Mat &b)
  17. {
  18. Mat ans;
  19. for (int j=;j<=n;j++)
  20. for (int i=;i<=n;i++)
  21. if (a[i][j]) ans.a[i]|=b.a[j];
  22. return ans;
  23. }
  24. Mat operator ^ (const Mat &b)
  25. {
  26. Mat ans;
  27. for (int j=;j<=n;j++)
  28. for (int i=;i<=n;i++)
  29. if (a[i][j]) ans.a[i]|=b.a[j];
  30. for (int i=;i<=n;i++) ans.a[i]|=a[i];
  31. return ans;
  32. }
  33. }mp,f[],base;
  34.  
  35. struct Point
  36. {
  37. int a,b,d;
  38. bool operator < (const Point &b) const {return d<b.d;}
  39. }p[maxn];
  40. int main()
  41. {
  42. scanf("%d%d",&n,&m);
  43. for (int i=;i<=m;i++) scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].d);
  44. sort(p+,p++m);
  45. if (p[].d) {puts("Impossible");return ;}
  46. p[m+].d=0x3f3f3f3f;
  47. base.a[][]=;
  48. for (int i=;i<=m+;i++)
  49. {
  50. while (i<=m+ && p[i].d==p[i-].d) {mp.a[p[i-].a][p[i-].b]=; i++;}
  51. int j,num=p[i].d-p[i-].d;
  52. for (j=;j>=;j--) if ((<<j)<=num) break;
  53. f[]=mp;
  54. for (int k=;k<=j;k++) f[k]=f[k-]^f[k-];
  55. Mat now; now=base; int cnt=;
  56. for (int k=j;k>=;k--) if (cnt+(<<k)<=num)
  57. {
  58. Mat tmp;tmp=now^f[k];
  59. bool flag=;
  60. for (int l=;l<=n;l++) flag|=tmp.a[l][n];
  61. if (!flag) cnt+=(<<k),now=tmp;
  62. }
  63. if (cnt!=num) {printf("%d\n",p[i-].d+cnt+);return ;}
  64. else
  65. {
  66. f[]=mp;
  67. for (int k=;k<=j;k++) f[k]=f[k-]*f[k-];
  68. cnt=;
  69. for (int k=j;k>=;k--) if (cnt+(<<k)<=num) base=base*f[k],cnt+=(<<k);
  70. Mat tmp; tmp=base;
  71. base.clear();
  72. for (int k=;k<=n;k++)
  73. for (int l=;l<=n;l++)
  74. if (tmp.a[k][l]) base.a[l][l]=;
  75. }
  76. }
  77. puts("Impossible");
  78. return ;
  79. }

CF576D. Flights for Regular Customers的更多相关文章

  1. CF576D Flights for Regular Customers 矩阵乘法 + Bitset优化

    %%%cxhscst2's blog Codeforces 576D Flights for Regular Customers(矩阵加速DP) 代码非常优美 + 简洁,学习到了 Code: #inc ...

  2. 「CF576D」 Flights for Regular Customers

    「CF576D」 Flights for Regular Customers 对不起我又想网络流去了 你看这长得多像啊,走过至少多少条边就是流量下界,然后没上界 但是这个题求的最少走多少条边啊...完 ...

  3. 【CodeForces】576 D. Flights for Regular Customers

    [题目]D. Flights for Regular Customers [题意]给定n个点m条边的有向图,每条边有di表示在经过该边前必须先经过di条边,边可重复经过,求1到n的最小经过边数.n,m ...

  4. Codeforces 576D Flights for Regular Customers(矩阵加速DP)

    题目链接  Flights for Regular Customers 首先按照$d$的大小升序排序 然后分成$m$个时刻,每条路径一次处理过来. $can[i][j]$表示当前时刻$i$能否走到$j ...

  5. 题解 CF576D 【Flights for Regular Customers】

    对每条边来说,可以走这条边的限制解除是按\(d\)的顺序,所以先对每条边按\(d\)排序. 然后考虑每两条边之间的处理,用一个矩阵表示当前走\(d\)步是否可以从一个点到另一个点,称其为状态矩阵,用另 ...

  6. (中等) 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 ...

  7. Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

    题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...

  8. Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)

    这破题调了我一天...错了一大堆细节T T 首先显然可以将边权先排序,然后逐个加进图中. 加进图后,倍增跑跑看能不能到达n,不能的话加新的边继续跑. 倍增的时候要预处理出h[i]表示转移矩阵的2^0~ ...

  9. Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)

    题目链接 http://codeforces.com/contest/576/problem/D 题解 把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\ ...

随机推荐

  1. 流程图软件draw.io

    工作中经常需要梳理一些流程图,时序图.以前用微软Visio绘制流程图(当然不是正版Visio).后来为了响应国家号召,改用processon(proceson.com)进行绘制流程图.Processo ...

  2. 一些常见的iOS面试问题,一眼就能看出 初级和高级工程师的区别

    前言 面试题中有一些一般性的问题,通常是会问到的.面试iOS应聘者时,切入点很重要,不同的切入点会导致不同的结果,没有找到合适的切入点也无法对应聘者有一个全面的了解. 所以下面的面试问题更多的是提供方 ...

  3. svg image 图片无法铺满 circle 的问题解决

    引子 使用d3.js绘制了力布图后,需要在circle中绘制图片,方法如下: // 绘制图片 drawPattern(gContainer) { let that = this; let gPatte ...

  4. 下载tortoisegit

    https://download.tortoisegit.org/tgit/ 藏经阁技术资料分享群二维码

  5. jquery 菜单展开与收缩参考脚本

    /* * metismenu - v1.1.3 * Easy menu jQuery plugin for Twitter Bootstrap 3 * https://github.com/onoku ...

  6. python程序展现图片遇到的坑

    使用cv2展示图片的时候遇到了问题,提示:TypeError: Required argument 'mat' (pos 2) not found 给定的图片路径是没得问题的,代码如下: 使用open ...

  7. C语言指针的理解以及指针的指针的理解

    指针指向的是内存地址编号,内存地址编号指向的是对应的内容. 我们需要一个变量,来储存内存地址编号,这个变量的值是一个内存地址编号,但是我们可以通过修改变量的值,来不断的改变内存地址编号. 但是,我们如 ...

  8. CF848A From Y to Y

    思路1: 每次贪心地选择满足i * (i - 1) / 2 <= k最大的i并从k中减去i * (i - 1) / 2,直至k为0.由于函数x * (x - 1) / 2的增长速度比2x要慢,所 ...

  9. CF540C Ice Cave

    思路: 搜索. 加回溯会超时,不加回溯就过了,不是很理解. 实现: #include <iostream> #include <cstdio> using namespace ...

  10. UVM基础之-------uvm factory机制override<博>

    override功能是UVM中一个比较重要的功能,这个功能也是在factory里面实现的,我们会在env或者具体的case中使用override功能. class case_x extends bas ...