题目大意

给你一个 \(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;
}

最新文章

  1. yum安装php,php-fpm
  2. Restful.Data v2.0发布,谢谢你们的支持和鼓励
  3. 【BZOJ-1113】海报PLA 单调栈
  4. JVM参数调优
  5. consul模板配置参数值示例
  6. asp.net中实现群发邮件功能
  7. JS 自定义回调函数callback
  8. Label 添加表情图片
  9. Entify Framewrok - Join的使用方法
  10. DataTables给每一列添加下拉框搜索
  11. 兼容 console 没删除引起 低级浏览器 报错问题
  12. static的加载先后顺序
  13. c++编程思想(一)--对象导言
  14. React是什么,为什么要使用它?
  15. PHP 关于判断输入日期是否合法
  16. 在ubuntu服务器上安装tomcat 9
  17. Navicat premium 12破解版
  18. kubernetes中service yaml文件的port作用
  19. 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)
  20. pytorch backward问题

热门文章

  1. WIN10下安装python3.7.2出现“尝试创建C:\Users\XX\AppData\Roaming\Microsoft\Installer时出错”
  2. 内核补丁热更新ceph内核模块
  3. SQL SERVER数据库使用过程中系统提示死锁处理办法
  4. 工作流(workflow)
  5. Hadoop大数据平台之Zookeeper搭建
  6. Java中对象在内存中的大小、分配等问题
  7. Sonar检测Math.abs(new Random().nextInt()) “Use the original value instead”
  8. mybatis 动态SQL 源码解析
  9. 使用Eclipse创建Maven的JSP项目
  10. Apache HTTPD 换行解析漏洞--CVE-2017-15715