题目大意

给你一个 \(n\) 个点,\(m\) 条边的有向图,每条边有一个权值 \(w_i\) ,每个节点有一个权值 \(a_i\) 。

你从节点 \(1\) 出发,每经过一个节点就可以获得该点的权值 \(a_i\) (起始点也可以获得,每个节点可以重复获得),问你经过的边权和恰好为 \(T\) 时,能获得的最大(点)权值和。

同时,题目还给出 \(k\) 个特殊条件,如果你在到达第 \(x_i\) 个节点时经过的边权和恰好为 \(t_i\) ,那么你就可以额外获得 \(y_i\) 的权值。

题解

我们可以观察题目数据范围:

对于所有测试点:

\(1≤n≤50\),\(n \leq m \leq 501\),\(0 \leq k \leq 200\),\(1 \leq t_i \leq T \leq 10^9\)。

\(1\leq wi \leq 5\),\(1 \leq c_i \leq 52501\),\(1 \leq u_i, v_i, x_i \leq n\),\(1 \leq y_i \leq 10^9\)。

发现每条边的边权不超过 \(5\) ,又考虑到我们需要恰好经过的边权为 \(T\) ,所以我们可以通过将边拆成点,同时建一个 \(floyd\) 矩阵,我们就可以利用矩阵快速幂来解决这个问题了。

但是我们发现还有一些特殊情况需要处理,我们可以考虑分段,每一段中间用矩阵快速幂,每一个相应的特殊情况给对应的位置添加值。

这样的复杂度是 $ O(125n^3k~logT)$ ,肯定是不行的,所以我们考虑优化。

由于我们每一次乘上的矩阵都是一样的,所以我们考虑预处理 \(2^k\) 的矩阵幂,然后每一个段都用类似于倍增的方式去处理。

这样的复杂度是 \(O(25~n^2~k~logT+125~n^3~logT)\) ,是可以接受的。

以上。

代码如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. const int N=55,M=505,K=205;
  5. int n,m,t,k;
  6. int u,v,w;
  7. int a[N],ksm[35];
  8. struct Matrix
  9. {
  10. int n,m;
  11. int h[N*5][N*5];
  12. Matrix() {n=m=0,memset(h,-1,sizeof(h));}
  13. void print()
  14. {
  15. for(int i=1;i<=n;++i)
  16. {
  17. for(int j=1;j<=m;++j)
  18. printf("%lld ",h[i][j]);
  19. printf("\n");
  20. }
  21. printf("\n");
  22. }
  23. }res[35],sta;
  24. Matrix operator*(const Matrix a,const Matrix b)
  25. {
  26. Matrix ans;
  27. ans.n=a.n,ans.m=b.m;
  28. for(int i=1;i<=ans.n;++i)
  29. {
  30. for(int j=1;j<=ans.m;++j)
  31. {
  32. for(int k=1;k<=a.m;++k)
  33. {
  34. if(a.h[i][k]>=0&&b.h[k][j]>=0)
  35. ans.h[i][j]=max(ans.h[i][j],a.h[i][k]+b.h[k][j]);
  36. }
  37. }
  38. }
  39. return ans;
  40. }
  41. struct Festival {int t,x,y;}s[K];
  42. bool cmp(Festival a,Festival b) {return a.t<b.t;};
  43. signed main()
  44. {
  45. // freopen("delicacy.in","r",stdin);
  46. // freopen("delicacy.out","w",stdout);
  47. cin>>n>>m>>t>>k;
  48. for(int i=1;i<=n;++i)
  49. scanf("%lld",&a[i]);
  50. res[0].n=res[0].m=n*5;
  51. for(int i=1;i<=n*5;++i)
  52. {
  53. if(i/5==(i-1)/5)
  54. res[0].h[i][i+1]=0;
  55. }
  56. for(int i=1;i<=m;++i)
  57. scanf("%lld%lld%lld",&u,&v,&w),
  58. res[0].h[(u-1)*5+w][(v-1)*5+1]=a[v];
  59. for(int i=1;i<=32;++i)
  60. res[i]=res[i-1]*res[i-1];
  61. sta.n=1,sta.m=n*5;
  62. sta.h[1][1]=a[1];
  63. for(int i=1;i<=k;++i)
  64. scanf("%lld%lld%lld",&s[i].t,&s[i].x,&s[i].y);
  65. sort(s+1,s+1+k,cmp);
  66. ksm[0]=1;
  67. for(int i=1;i<=32;++i)
  68. ksm[i]=(ksm[i-1]<<1);
  69. int tmp=0;
  70. for(int i=1;i<=k;++i)
  71. {
  72. for(int j=32;j>=0;--j)
  73. {
  74. if(tmp+ksm[j]<=s[i].t)
  75. tmp+=ksm[j],sta=sta*res[j];
  76. }
  77. if(sta.h[1][(s[i].x-1)*5+1]>=0)
  78. sta.h[1][(s[i].x-1)*5+1]+=s[i].y;
  79. }
  80. for(int i=32;i>=0;--i)
  81. {
  82. if(tmp+ksm[i]<=t)
  83. tmp+=ksm[i],sta=sta*res[i];
  84. }
  85. printf("%lld\n",sta.h[1][1]);
  86. return 0;
  87. }

P6772 [NOI2020]美食家的更多相关文章

  1. 洛谷 P6772 - [NOI2020]美食家(广义矩阵快速幂)

    题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,第 \(0\) 天的时候你在 \(1\) 号城市,第 \(T\) 天的时候你要回到 \(1\) 号城市. 每条边上的边权表示从城 ...

  2. [XIN算法应用]NOI2020美食家

    XIN(\(updated 2021.6.4\)) 对于很多很多的题目,发现自己并不会之后,往往会直接冲上一个XIN队算法,然而,这样 \(\huge{\text{鲁莽}}\) 的行为只能获得 TLE ...

  3. [NOI2020]美食家 题解

    题意分析 给出一个带权有向图,要求从节点 $1$ 出发,经过恰好 $T$ 的边权和,回到节点 $1$ ,求可经过的最大点权和.特别地,经过的边权和达到部分特殊数时,会有某个点的点权发生改变. 思路分析 ...

  4. [NOI2020] 美食家

    很好,自己会做NOI签到题了,去年只要会这题,再多打点暴力,\(Ag\)到手,希望今年\(NOI\)同步赛过\(Ag\)线吧,得有点拿得出手的成绩证明啊. 考虑\(T\)非常大,\(n\)又很小. 想 ...

  5. 【NOI2020】美食家(矩阵)

    Description 给定一张有向图,\(n\) 个顶点,\(m\) 条边.第 \(i\) 条边从 \(u_i\) 到 \(v_i\),走完该边的用时为 \(w_i\).每一个点有一个价值 \(c\ ...

  6. XIN队算法

    XIN队算法 注:名称由莫队算法改编而来 从luogu搬过来了... \(newly\;upd:2021.7.8\) \(newly\;upd:2021.6.6\) OI至高算法,只要XIN队算法打满 ...

  7. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  8. [BZOJ1691][Usaco2007 Dec]挑剔的美食家

    [BZOJ1691][Usaco2007 Dec]挑剔的美食家 试题描述 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了. ...

  9. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家( 平衡树 )

    按鲜嫩程度排个序, 从大到小处理, 用平衡树维护价值 ---------------------------------------------------------------------- #i ...

随机推荐

  1. Ceph中的Copyset概念和使用方法

    前言 copyset运用好能带来什么好处 降低故障情况下的数据丢失概率(增加可用性) 降低资源占用,从而降低负载 copyset的概念 首先我们要理解copyset的概念,用通俗的话说就是,包含一个数 ...

  2. 压缩css与js

    使用yuicompressor 进行css和js的压缩 #! /bin/sh yasuocss="java -jar /root/yuicompressor-2.4.8.jar --type ...

  3. HTTP介绍(一)

    超文本传输协议(HTTP)是一种用于分布式,协作式超媒体信息系统的应用程序层协议.HTTP是万维网(World Wide Web)数据通信的基础,超文本文档包括指向用户可以轻松访问的其他资源的超链接, ...

  4. Python_列表相减(判断长度后长的减短的)

    #定义一个方法,可进行列表相减 class V(object): def __init__(self,*value): self.value=value def __sub__(self,other) ...

  5. 算法题目:北邮python 3-C 排队前进

    一道python作业的题目,比较有意思,题目如下: 题目描述 有 n 个人排队向一个方向前进,他们前进的速度并不一定相同. 最开始即 t=0 时,每个人的位置并不相同.可以把他们放在数轴上,设他们前进 ...

  6. php插入一百万测试数据(实例)

    <?phpset_time_limit(0);function a(){ header("Content-Type:text/html;charset=utf-8"); $s ...

  7. 去年去阿里面试,被问到java 多线程,我是这样手撕面试官的

    1.多线程的基本概念 1.1进程与线程 程序:是为完成特定任务,用某种语言编写的一组指令的集合,即一段静态代码,静态对象. 进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,每个程 ...

  8. 轻松学编曲,论FL钢琴卷帘

    我们平时做视频时难免要用到音乐,市面上又有很多调音编曲软件,我们该如何选择呢?在这里笔者给大家推荐一款音乐制作软件FL Studio20,也就是业内知名度很高的水果音乐制作软件,这款音乐制作软件笔者用 ...

  9. yii的pathinfo方式实现

    yii2.0在浏览器中默认查看控制器下的方法是  http://ltbk.cn/index.php?r=login/login 要是在浏览器上输出 http://ltbk.cn/index.php/l ...

  10. 无效的HTTP_主机头Invalid HTTP_HOST header: '192.168.56.100:8888'. You may need to add '192.168.56.100' to ALLOWED_HOSTS.

    Invalid HTTP_HOST header: '192.168.56.100:8888'. You may need to add '192.168.56.100' to ALLOWED_HOS ...