题目大意

给你一个 \(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)\) ,是可以接受的。

以上。

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=55,M=505,K=205;
int n,m,t,k;
int u,v,w;
int a[N],ksm[35];
struct Matrix
{
int n,m;
int h[N*5][N*5];
Matrix() {n=m=0,memset(h,-1,sizeof(h));}
void print()
{
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
printf("%lld ",h[i][j]);
printf("\n");
}
printf("\n");
}
}res[35],sta;
Matrix operator*(const Matrix a,const Matrix b)
{
Matrix ans;
ans.n=a.n,ans.m=b.m;
for(int i=1;i<=ans.n;++i)
{
for(int j=1;j<=ans.m;++j)
{
for(int k=1;k<=a.m;++k)
{
if(a.h[i][k]>=0&&b.h[k][j]>=0)
ans.h[i][j]=max(ans.h[i][j],a.h[i][k]+b.h[k][j]);
}
}
}
return ans;
}
struct Festival {int t,x,y;}s[K];
bool cmp(Festival a,Festival b) {return a.t<b.t;};
signed main()
{
// freopen("delicacy.in","r",stdin);
// freopen("delicacy.out","w",stdout);
cin>>n>>m>>t>>k;
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
res[0].n=res[0].m=n*5;
for(int i=1;i<=n*5;++i)
{
if(i/5==(i-1)/5)
res[0].h[i][i+1]=0;
}
for(int i=1;i<=m;++i)
scanf("%lld%lld%lld",&u,&v,&w),
res[0].h[(u-1)*5+w][(v-1)*5+1]=a[v];
for(int i=1;i<=32;++i)
res[i]=res[i-1]*res[i-1];
sta.n=1,sta.m=n*5;
sta.h[1][1]=a[1];
for(int i=1;i<=k;++i)
scanf("%lld%lld%lld",&s[i].t,&s[i].x,&s[i].y);
sort(s+1,s+1+k,cmp);
ksm[0]=1;
for(int i=1;i<=32;++i)
ksm[i]=(ksm[i-1]<<1);
int tmp=0;
for(int i=1;i<=k;++i)
{
for(int j=32;j>=0;--j)
{
if(tmp+ksm[j]<=s[i].t)
tmp+=ksm[j],sta=sta*res[j];
}
if(sta.h[1][(s[i].x-1)*5+1]>=0)
sta.h[1][(s[i].x-1)*5+1]+=s[i].y;
}
for(int i=32;i>=0;--i)
{
if(tmp+ksm[i]<=t)
tmp+=ksm[i],sta=sta*res[i];
}
printf("%lld\n",sta.h[1][1]);
return 0;
}

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. rgw前端替换civetweb为beast

    前言 ceph的rgw现在提供了两种前端, civetweb和beast 配置 修改配置文件 rgw_frontends = civetweb port=7481 为 rgw frontends = ...

  2. vue路由懒加载方式

    方式一:结合Vue的异步组件和Webpack的代码分析 const Home = resole => {require.ensure(['../components/Home.vue'],() ...

  3. cookie和session的关系和区别

    1.为什么会用到cookie和session 由于http请求是一种无状态的请求,一旦数据交换完毕便会关闭请求,再次交换数据则要再次发起请求,所以服务端无法通过连接追踪会话,确定用户身份,而cooki ...

  4. Android ALSPS驱动分析

    一.alsps的初始化函数和重要结构体 epl2182_init // Epl2182.c (kernel-3.10\drivers\misc\mediatek\alsps\epl2182-new) ...

  5. 使用Camtasia制作冰雪奇缘视频

    冰雪奇缘的精良制作,以及场景的华丽,让很多女孩子都很喜欢.对于其中美丽的冰雪场景,我们还可以使用Camtasia(Windows系统)教程录制软件来做冰雪奇缘视频. Camtasia教程录制软件是一款 ...

  6. 慢SQL优化:where id in (select max(id)...) 改为join后性能提升400倍

    背景 有两张表,都是主键递增,类似于主表和明细表: statistics_apply:统计申请表,主键applyId,7万多条记录 statistics_apply_progress:统计申请进度表( ...

  7. leetcode152. 乘积最大子序列

    给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数).示例 1:输入: [2,3,-2,4]输出: 6解释: 子数组 [2,3] 有最大乘积 6.示例 2:输入: ...

  8. thinkPHP 无法加载控制器:Hello

    出现这种问题的情况下要看看: (1).控制器的名称是否写对,控制器的命名规范(别忘下class) 控制器的命名规则1.必须采用大驼峰的命名规则2.必须以Controller.class.php来结尾I ...

  9. 安装了向日葵或TeamViewer导致系统亮度无法调节

    1.向日葵 安装向日葵造成无法调节亮度的原因:可能为了使用向日葵的黑屏模式功能,误装了向日葵的驱动.建议不要使用该功能. 关于安装向日葵的用户,请参考以下步骤解决: 请保持电脑处于联网状态,并关闭了向 ...

  10. IEEE754标准浮点数表示与舍入

    原文地址:https://blog.fanscore.cn/p/26/ 友情提示:本文排版不太好,但内容简单,请耐心观看,总会搞懂的. 1. 定点数 对于一个无符号二进制小数,例如101.111,如果 ...