题目传送门(内部题83)


输入格式

  第一行两个整数$n,m$
  接下来$m$行,每行三个整数,$u,v,w$,表示从$u$到$v$有一条权值为$w$的边
  接下来一行有一个整数$q$,表示$q$天
  接下来$q$行,每行三个整数,$s_i,t_i,k_i$,表示从$s_i$到$t_i$至少经过$k_i$条边


输出格式

  一共$q$行,每行一个整数,表示在第$i$天中的最短距离,如果没有符合要求的答案,输出$-1$。


样例

样例输入:

3 3
1 2 1
2 3 10
3 1 100
3
1 1 1
1 2 1
1 3 1

样例输出:

111
1
11


数据范围与提示

  对于$30\%$的数据,$k_i\leqslant 50$
  对于另外$30\%$的数据,$q\leqslant 50$
  对于$100\%$的数据,$n\leqslant 50,m\leqslant 10,000,wi\leqslant 10,000,q\leqslant 100,000,ki\leqslant 10,000$


题解

$DP$和分块可能很难接合在一起,但是他们做到了。

不妨设$f[i][j][k]$表示从$i$到$j$恰好走$k$步的方案数,稍做修改就能做到至少走$k$步的方案数。

再设$p[i][j]$表示从$i$到$j$恰好走$100$步的方案数,这个数组也就是这道题的关键,将其分块了。

最后设$g[i][j][k]$表示从$i$到$j$恰好走$100\times k$的方案数即可。

最后答案就是$\min\limits_{i=1}^n(g[s][i][k/100]+f[i][t][k\%100])$。

时间复杂度:$\Theta(100\times n+q\times n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,m,q;
int d[51][51],p[51][51],g[51][51][200],f[51][51][200];
int main()
{
memset(d,0x3f,sizeof(d));
memset(g,0x3f,sizeof(g));
memset(f,0x3f,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
d[u][v]=min(d[u][v],w);
}
for(int i=1;i<=n;i++)
{
f[i][i][0]=0;
for(int j=0;j<n+100;j++)
for(int k=1;k<=n;k++)
for(int l=1;l<=n;l++)
f[i][l][j+1]=min(f[i][l][j+1],f[i][k][j]+d[k][l]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
p[i][j]=f[i][j][100];
for(int k=n+100;~k;k--)
f[i][j][k]=min(f[i][j][k],f[i][j][k+1]);
}
for(int i=1;i<=n;i++)
{
g[i][i][0]=0;
for(int j=0;j<100;j++)
for(int k=1;k<=n;k++)
for(int l=1;l<=n;l++)
g[i][l][j+1]=min(g[i][l][j+1],g[i][k][j]+p[k][l]);
}
scanf("%d",&q);
while(q--)
{
int s,t,k,ans=0x3f3f3f3f;
scanf("%d%d%d",&s,&t,&k);
for(int i=1;i<=n;i++)ans=min(ans,f[i][t][k%100]+g[s][i][k/100]);
if(ans==0x3f3f3f3f)puts("-1");
else printf("%d\n",ans);
}
return 0;
}

rp++

[CSP-S模拟测试]:旅行计划(分块+DP)的更多相关文章

  1. [CSP-S模拟测试]:Market(背包DP)

    题目描述 在比特镇一共有$n$家商店,编号依次为$1$到$n$.每家商店只会卖一种物品,其中第$i$家商店的物品单价为$c_i$,价值为$v_i$,且该商店开张的时间为$t_i$. $Byteasar ...

  2. [CSP-S模拟测试]:B(期望DP)

    题目传送门(内部题151) 输入格式 第一行一个整数$N$. 第二行$N$个整数,第$i$个为$a_i$. 输出格式 一行一个整数,表示答案.为避免精度误差,答案对$323232323$取模. 即设答 ...

  3. [CSP-S模拟测试]:密码(数位DP+库默尔定理)

    题目描述 为了揭穿$SERN$的阴谋,$Itaru$黑进了$SERN$的网络系统.然而,想要完全控制$SERN$,还需要知道管理员密码.$Itaru$从截获的信息中发现,$SERN$的管理员密码是两个 ...

  4. [CSP-S模拟测试]:硬币(博弈论+DP+拓展域并查集)

    题目传送门(内部题135) 输入格式 第一行包含一个整数$T$,表示数据组数. 对于每组数据,第一行两个整数$h,w$,表示棋盘大小. 接下来$h$行,每行一个长度为$w$的字符串,每个位置由为$o, ...

  5. [CSP-S模拟测试]:军训队列(DP+乱搞)

    题目描述 有$n$名学生参加军训,军训的一大重要内容就是走队列,而一个队列的不规整程度是该队中最高的学生的身高与最矮的学生的身高差值的平方.现在要将$n$名参加军训的学生重新分成$k$个队列,每个队列 ...

  6. [CSP-S模拟测试]:优化(贪心+DP)

    题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连 ...

  7. [CSP-S模拟测试]:玩具(概率DP)

    题目描述 这个故事发生在很久以前,在$IcePrincess\text{_}1968$和$IcePrince\text{_}1968$都还在上幼儿园的时候. $IcePrince\text{_}196 ...

  8. [CSP-S模拟测试]:超级树(DP)

    题目传送门(内部题5) 输入格式 一行两个整数$k$.$mod$,意义见上. 输出格式 一行一个整数,代表答案. 样例 样例输入1: 2 100 样例输出1: 样例输入2: 3 1000 样例输出2: ...

  9. [CSP-S模拟测试]:Park(树上DP)

    题目描述 公园里有$n$个雕像,有$n-1$条道路分别连接其中两个雕像,任意两个雕像可以直接或间接相连.现在每个景点$i$聚集着$P_i$只鸽子,旅行家手里有$v$数量的面包屑. 一旦旅行家在雕像$i ...

随机推荐

  1. 拼音检查python

    #coding=utf-8 #!/usr/bin/python import sys, re, collections #读入文件 def read_file(filename): try: fp = ...

  2. 【6.18校内test】T1多项式输出

    日常题前废话: 首先so amazing 的一件事,因为在洛谷上立下了的flag,然后这次考试前两道题都是刚刚做过不久的题emmm(相当于白送200吗qwq,但是这阻挡不了我第三题不会的脚步qwq) ...

  3. 2019ICPC徐州游记

    裂开QAQ 热身赛听隔壁电科的猛男们说赛前别做题,结果我们3个憨憨还是跑到网吧打哈尔滨的重现赛.结果真的炸裂了,队友D被E题卡哭了,我和队友Z被I题搞炸. 回宾馆的路上都害怕明天裂开. 果然想什么坏事 ...

  4. gdb笔记 ---《Linux.C编程一站式学习》

    gdb笔记 ---<Linux.C编程一站式学习> 单步执行和跟踪函数调用 函数调试实例 #include <stdio.h> int add_range(int low, i ...

  5. C++学习——在C文件中调用C++文件中的函数

    1.CPP文件中的内容 #include "mytest.h" #include <iostream> using namespace std; int add(con ...

  6. 2018-2019 ICPC, NEERC, Southern Subregional Contest (codeforces 1070)

    A. 直接从状态(0,0)bfs, 这样一定是最小的 #include <iostream> #include <sstream> #include <algorithm ...

  7. jQuery中outerWidth()方法

    截图自:菜鸟教程https://www.runoob.com/jquery/html-outerwidth.html

  8. linux的安全--Selinux,tcp_wrappers,iptables使用

    一.linux安全 安全主要是端口与服务的对应配置 1.1 linux安全主要通过下面三个进行加固 Selinux----主要是对内核的访问权限加以控制 tcp_wrappers---一定程度上限制某 ...

  9. Java引用与C语言指针的区别

    1.现象 指针在运行时可以改变其所指向的值(地址)即指向其它变量,而引用一旦和某个对象绑定后就不能再改变,总是指向最初的对象. 2.编译 程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变 ...

  10. RHEL7使用systemctl管理服务

    1.   systemctl命令 说明 systemctl    start   [unit type] 启动服务 systemctl    stop   [unit type] 停止服务 syste ...