[CSP-S模拟测试]:任务分配(最短路+贪心+DP)
题目传送门(内部题149)
输入格式
每个测试点第一行为四个正整数$n,b,s,m$,含义如题目所述。
接下来$m$行,每行三个非负整数$u,v,l$,表示从点$u$到点$v$有一条权值为$l$的有向边,数据保证图是强连通的,也就是任意两个点之间都可以互相走到。
输出格式
对每组数据输出一行一个非负整数表示答案。
样例
样例输入1:
5 4 2 10
5 2 1
2 5 1
3 5 5
4 5 0
1 5 1
2 3 1
3 2 5
2 4 5
2 1 1
3 4 2
样例输出1:
13
样例输入2:
5 4 2 10
5 2 1
2 5 1
3 5 5
4 5 10
1 5 1
2 3 1
3 2 5
2 4 5
2 1 1
3 4 2
样例输出2:
24
数据范围与提示
每个测试点$5$分,各个测试点数据范围如下:

除此之外,数据中可能会均匀出现一些$s$值比较小的点。
对于所有的测试点,均有$m\leqslant 50,000,1\leqslant s\leqslant b<n,0\leqslant l\leqslant 10,000$,给定的有向图合法且强连通。
题解
先求出每个点到总部的正反最短路,建反向边即可。
化一下式子即可发现每一个点的代价为它的正反最短路长度和乘上它所在子项目有几个分部$-1$。
利用贪心的思想,小的放在一起,大的放在一起一定更优,于是可以排个序。
接着考虑$DP$,设$dp[i][j]$表示选到$i$,分了$j$组的最小代价,但是发现时间复杂度是$\Theta(n^3)$的,接着考虑优化。
在最优解中$dis$从小到大依次划分得到的段的长度一定是单调不增的,所以只有$[i-\frac{i}{j},i)$才能更新$dp[i][j]$。
那么现在算法的时间复杂度就是:$\Theta(n^2(\frac{1}{1}+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n}))=\Theta(n^2\log n)$。
由于时限为$3s$所以跑过去绰绰有余。
时间复杂度:$\Theta(n^2\log n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;}e[100001];
int head[2][5001],cnt;
int n,b,s,m;
int dis[2][5001];
bool vis[5001];
long long sum[5001],dp[5001][5001];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
void add(bool id,int x,int y,int w)
{
e[++cnt].nxt=head[id][x];
e[cnt].to=y;
e[cnt].w=w;
head[id][x]=cnt;
}
void Dij0()
{
q.push(make_pair(0,b+1));
dis[0][b+1]=0;
while(q.size())
{
int x=q.top().second;q.pop();
if(vis[x])continue;vis[x]=1;
for(int i=head[0][x];i;i=e[i].nxt)
if(dis[0][e[i].to]>dis[0][x]+e[i].w)
{
dis[0][e[i].to]=dis[0][x]+e[i].w;
q.push(make_pair(dis[0][e[i].to],e[i].to));
}
}
}
void Dij1()
{
memset(vis,0,sizeof(vis));
q.push(make_pair(0,b+1));
dis[1][b+1]=0;
while(q.size())
{
int x=q.top().second;q.pop();
if(vis[x])continue;vis[x]=1;
for(int i=head[1][x];i;i=e[i].nxt)
if(dis[1][e[i].to]>dis[1][x]+e[i].w)
{
dis[1][e[i].to]=dis[1][x]+e[i].w;
q.push(make_pair(dis[1][e[i].to],e[i].to));
}
}
}
int main()
{
scanf("%d%d%d%d",&n,&b,&s,&m);
for(int i=1;i<=m;i++)
{
int a,b,l;
scanf("%d%d%d",&a,&b,&l);
add(0,a,b,l);add(1,b,a,l);
}
memset(dis,0x3f,sizeof(dis));
Dij0();Dij1();
for(int i=1;i<=b;i++)
sum[i]=dis[0][i]+dis[1][i];
sort(sum+1,sum+b+1);
for(int i=1;i<=b;i++)sum[i]+=sum[i-1];
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=b;i++)
for(int j=1;j<=s;j++)
for(int k=i-i/j;k<i;k++)
{
if((sum[i]-sum[k])*(i-k-1)>=dp[i][j])break;
dp[i][j]=min(dp[i][j],dp[k][j-1]+(sum[i]-sum[k])*(i-k-1));
}
printf("%lld",dp[b][s]);
return 0;
}
rp++
[CSP-S模拟测试]:任务分配(最短路+贪心+DP)的更多相关文章
- [CSP-S模拟测试]:二叉搜索树(DP+贪心)
题目传送门(内部题99) 输入格式 第一行一个整数$n$,第二行$n$个整数$x_1\sim x_n$. 输出格式 一行一个整数表示答案. 样例 样例输入: 58 2 1 4 3 样例输出: 数据范围 ...
- [CSP-S模拟测试]:C(三分+贪心)
题目传送门(内部题46) 输入格式 第一行$3$个整数$n,m,t$.第二行$n$个整数,表示$P_i$.接下来$m$行每行两个整数,表示$L_i,R_i$. 输出格式 一行一个整数表示答案. 样例 ...
- [CSP-S模拟测试]:括号密码(贪心)
题目描述 在“无限神机”的核心上,有一个奇怪的括号密码,密码初始已经有一个括号序列,有$n$个限制条件,每个限制条件描述为$l_i$和$r_i$,表示区间$[l_i,r_i]$的括号序列必须合法.调整 ...
- [CSP-S模拟测试]:trade(反悔贪心)
题目传送门(内部题62) 输入格式 第一行有一个整数$n$.第二行有$N$个整数:$a_1\ a_2\ a_3\cdot\cdot\cdot a_n$. 输出格式 一行一个整数表示最大收益. 样例 样 ...
- [CSP-S模拟测试]:Graph(图论+贪心)
题目描述 给定一张$n$个点$m$条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通你想在这张图上进行若干次旅游,每次旅游可以任选一个点$x$作为起点,再走到一个与 $x$直接有边相连的点$ ...
- [CSP-S模拟测试]:虎(DFS+贪心)
题目传送门(内部题15) 输入格式 第一行一个整数$n$,代表点数接下来$n-1$行,每行三个数$x,y,z$,代表点$i$与$x$之间有一条边,若$y$为$0$代表初始为白色,否则为黑色,若$z$为 ...
- [CSP-S模拟测试]:Emotional Flutter(贪心)
题目传送门(内部题51) 输入格式 第一行一个整数$t$表示数据组数.每组数据的第一行有三个整数$s,k,n$.第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度. 输出格式 ...
- 联赛模拟测试25 C. Repulsed 贪心+树形DP
题目描述 分析 考虑自底向上贪心 \(f[x][k]\) 表示 \(x\) 下面距离为 \(k\) 的需要灭火器的房间数,\(g[x][k]\) 表示 \(x\) 下面距离为 \(k\) 的多余灭火器 ...
- [CSP-S模拟测试]:字符交换(贪心+模拟)
题目传送门(内部题136) 输入格式 输入文件第一行为两个正整数$n,k$,第二行为一个长度为$n$的小写字母字符串$s$. 输出格式 输出一个整数,为对字符串$s$进行至多$k$次交换相邻字符的操作 ...
随机推荐
- QT 获取字体大小
QFont font(androidFont); QFontInfo fInfo(font); qDebug()<<"FFFFFFFFFFFFFFFFFFFFFFFPPPSIZE ...
- 【Git的基本操作四】永久删除文件后找回
永久删除文件后找回 1. 已经添加到本地库的文件 使用 reset 命令回退到未删除的历史记录即可 2.添加到缓存区,没有提交到本地库的文件找回 git reset --hard HEAD 命令即可找 ...
- 密码基础知识(2)以RSA为例说明加密、解密、签名、验签
密码基础知识(1)https://www.cnblogs.com/xdyixia/p/11528572.html 一.RSA加密简介 RSA加密是一种非对称加密.是由一对密钥来进行加解密的过程,分别称 ...
- web录音——上传录音文件
捕获麦克风 一. 前言 公司项目需要实现web录音,刚刚好接手此功能,由于之前未接触过,在网上找了些资料做对比 ) https://www.cnblogs.com/starcrm/p/51 ...
- JavaMaven【四、坐标&构件】
maven的依赖都是使用坐标找到对应的构件来进行的 坐标 即groupId+artifactId+version 上图第一个红框是本项目的坐标 第二个红框是依赖的项目的坐标 构件 坐标对应的jar包 ...
- Android 计算器制作 2.注册View 构建函数
鄙人新手 整了 快两天 终于搞定了.. 1.首先是MainActivity 中 在Oncreate函数中 注册 2.按+ 或者 - 号 来分成两大字符串 s1 和 s2 再将s2 分为更小的s1 和 ...
- 重新编译mysqldump,使mysqldump具有进度输出功能
重新编译mysql,使mysqldump具有进度输出功能 安装编译过程所必须的依赖包和环境 yum install -y gcc cmake boost boost-build boost-devel ...
- socket 测试工具java
SocketTest.jar http://sockettest.sourceforge.net/
- UVa400 Unix is
The computer company you work for is introducing a brand new computer line and is developing a new U ...
- 内置对象-Math
1.随机数 Math.random() 1)获得0-1之间的随机数 2)0到100:Math.round(Math.random()*100) 2.max:求最大值 ,,,) console.log( ...