zoukankan      html  css  js  c++  java
  • [NOI2020]美食家 题解

    考虑拆点(,)把每个点拆成(5)个点(,) (p_{i,t}(0leq t leq 4))表示(t)秒之后到达点(i.)

    对于每个正整数(t,)把所有的(p_{i,t})连向(p_{i,t-1}.)

    然后每一条边((x,y,t))就可以变成((p_{x,0},p_{y,t-1}),)就可以矩阵乘法来维护这个东西了(.)

    不难据此得到转移矩阵(A.)

    然后我们相当于要向量乘矩阵(,)一共需要乘(k)(A)的若干次方(,)那么我们预处理一下(A^2,A^4,A^8,...A^{2^{30}})即可(.)

    复杂度(O((nw)^3 log T+k(nw)^2 log T).)

    代码(:)

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int N = 50,M = 505,K = 205,V = 250;
    const LL INF = 1ll << 60;
    
    int L;
    struct Mat{
    	LL a[V][V];
    	inline void init(){
    		for (int i = 0; i < L; ++i) for (int j = 0; j < L; ++j) a[i][j] = -INF;
    	}
    };
    struct Vec{
    	LL a[V];
    	inline void init(){
    		for (int i = 0; i < L; ++i) a[i] = -INF;	
    	}
    };
    Mat operator * (const Mat A,const Mat B){
    	static Mat T; T.init();
    	for (int k = 0; k < L; ++k) for (int i = 0; i < L; ++i) for (int j = 0; j < L; ++j)
    		if (A.a[i][k] + B.a[k][j] > T.a[i][j]) T.a[i][j] = A.a[i][k] + B.a[k][j];
    	return T;
    }
    Vec operator * (const Mat A,const Vec B){
    	static Vec T; T.init();
    	for (int i = 0; i < L; ++i) for (int j = 0; j < L; ++j)
    		if (A.a[j][i] + B.a[j] > T.a[i]) T.a[i] = A.a[j][i] + B.a[j];
    	return T;
    }
    
    int n,m,T,k,c[N];
    int ex[M],ey[M],ez[M];
    Mat I,Tr,A[30];
    Vec st; int nowt;
    int id[N][5];
    struct Festival{
    	int t,x,y;
    }ev[K];
    int main(){
    //	freopen("delicacy.in","r",stdin);
    //	freopen("delicacy.out","w",stdout);
    	int i,j;	
    	cin >> n >> m >> T >> k;
    	I.init(); L = n * 5;
    	for (i = 0; i < n; ++i) cin >> c[i];
    	for (i = 0; i < n; ++i) I.a[i][i] = 0;
    	for (i = 0; i < n; ++i) for (j = 0; j < 5; ++j) id[i][j] = j * n + i;
    	for (i = 1; i <= m; ++i) cin >> ex[i] >> ey[i] >> ez[i],--ex[i],--ey[i];
    	Tr.init();
    	for (i = 0; i < n; ++i)
    	for (j = 1; j < 5; ++j) Tr.a[id[i][j]][id[i][j-1]] = (j==1) ? (c[i]) : (0);
    	for (i = 1; i <= m; ++i) Tr.a[id[ex[i]][0]][id[ey[i]][ez[i]-1]] = (ez[i]==1) ? (c[ey[i]]) : (0);
    	A[0] = Tr;
    	for (i = 1; i < 30; ++i) A[i] = A[i-1] * A[i-1];
    	
    	for (i = 1; i <= k; ++i) cin >> ev[i].t >> ev[i].x >> ev[i].y,--ev[i].x;
    	for (i = 1; i <= k; ++i) for (j = i+1; j <= k; ++j) if (ev[j].t < ev[i].t) swap(ev[i],ev[j]);
    	if (ev[k].t != T){ ++k; ev[k].t = T,ev[k].x = ev[k].y = 0; }	
    	st.init(); st.a[id[0][0]] = c[0]; nowt = 0;
    	for (i = 1; i <= k; ++i){
    		int dt = ev[i].t - nowt;
    		for (j = 0; j < 30; ++j) if (dt>>j&1) st = A[j] * st;
    		if (st.a[ev[i].x] >= 0) st.a[ev[i].x] += ev[i].y; 
    		nowt = ev[i].t;
    	}
    	if (st.a[0] < 0) st.a[0] = -1;
    	cout << st.a[0] << '
    ';
    }
    
  • 相关阅读:
    Android 画布绘图
    Android 4.2.2原生Launcher修改使之可以运行过程小结
    canvas的translate、scale、rotate等方法
    WorkSpace介绍
    Libgdx New 3D API 教程之 -- 加载3D场景的背后-第二部分
    Libgdx New 3D API 教程之 -- 使用Libgdx加载模型
    LibGdx----Texture, TextureRegion, SpriteBatch
    libgdx学习之Camera
    Java伪代码
    读大道至简之感
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13581287.html
Copyright © 2011-2022 走看看