[World Final 2016] Branch Assignment
链接
先求出正置边和反置边时b+1到前b个点的最短路dis[0/1][x](x∈[1,b]),
令D[x]=dis[0][x]+dis[1][x]
然后分组后每个x对代价的贡献为D[x]*(所在组中元素个数-1)
考虑DP决策分组过程,发现没有一个很好的序,
不过为了使得代价小,应该把D小的放在个数大的组里,D大的放在个数少的组里
由此可以想出,应该是大小相近的元素放在了同一组中,这意味着,先排序,在划分成s段,的所有情况包含了原问题的最优解
于是把D[1~b]排序后,有方程
$f[i][j]=MIN_{k=0}^{j-1}[f[i-1][k]+(j-k-1)*(sum[j]-sum[k])]$
$O(n^3)$
其中:f[i][j]表示把前j个分成i组的最小值,sum为D的前缀和
非法状态均置为INF
由于可以粗略的知道这个东西在j确定,i为自变量的函数图像上有凸性
(可以玄学地认为,最开始的时候,多划分一刀可以造成很大的改变,随着划分次数越来越多,多划分一刀的改变越来越微小)
于是,可以使用带权二分来优化这一DP
即,消去对划分次数的限制,通过二分来找到一个合适的划分附加代价,使得即使不限制划分次数,最后的最优解也恰好满足我们对划分数的限制
这样有了一个新的方程
$f'[j]=MIN_{k=0}^{j-1}[f'[k]+(j-k-1)*(sum[j]-sum[k])]+C$
$O(n^2log)$
考虑优化转移过程
拆开方程得到
$f'[j]=MIN_{k=0}^{j-1}[f'[k]+(k+1)sum[k]-ksum[j]-jsum[k]]+(j-1)sum[j]+C$
在方程中
当固定j不动时
随k增加,f'[k]+(k+1)sum[k]项增加,-ksum[j]-jsum[k]项减小
而随j的增加,含j的项(即-ksum[j]-jsum[k])对答案的影响加剧,于是,随j的增加,j的最优决策中的k会单调变大(随j的增加,我们决策时更为看重含j项,为了使含j项减小,我们试图使用更大的k)
这意味着这个方程有决策单调性
本题通过带权二分和决策单调性优化可以做到$O(nlog^2)$
(感觉最近状态很差,午休一直睡不着来着,几个月了吧,先是用N^2log给方哥号上贡献了半屏T,又以为可以nlog做,然后贡献了半屏Wa,最后才发现决策单调性)
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define P pair <int ,int >
using namespace std;
priority_queue <P ,vector <P > ,greater <P > > PQ ;
int n,b,s,r;
struct INP{
int u,v,val;
}inp[];
struct ss{
int to,next,val;
}e[];
int first[],num;
LL d[],f[],sum[];
int lin[],dis[],que[],grt_st[];
void build(int ,int ,int );
void dij(int );
bool check(LL );
LL ask(int ,int );
int main()
{
int i,j,k,l;
LL L,R,mid;
scanf("%d%d%d%d",&n,&b,&s,&r);
for(i=;i<=r;i++){
scanf("%d%d%d",&inp[i].u,&inp[i].v,&inp[i].val);
build(inp[i].u,inp[i].v,inp[i].val);
}
dij(b+);
for(i=;i<=b;i++) d[i]=dis[i];
memset(first,,sizeof(first)),num=;
for(i=;i<=r;i++)
build(inp[i].v,inp[i].u,inp[i].val);
dij(b+);
for(i=;i<=b;i++) d[i]+=dis[i];
sort(d+,d+b+);
for(i=;i<=b;i++) sum[i]=sum[i-]+d[i];
L=,R=b*sum[b],mid=(L+R)>>;
while(R-L>=){
if(check(mid)) L=mid;
else R=mid-;
mid=(L+R)>>;
}
for(mid=R;mid>=L;mid--)
if(check(mid)){
printf("%lld\n",f[b]-s*mid);
return ;
}
return ;
}
void build(int f,int t,int val){
e[++num].next=first[f];
e[num].to=t,e[num].val=val;
first[f]=num;
}
void dij(int S){
int i,U;
memset(dis,0x3f,sizeof(dis));
dis[S]=;
P u,v;
u.first=,u.second=S;
PQ.push(u);
while(!PQ.empty()){
u=PQ.top();
PQ.pop();
U=u.second;
for(i=first[U];i;i=e[i].next)
if(dis[e[i].to]>dis[U]+e[i].val){
dis[e[i].to]=dis[U]+e[i].val;
v.first=dis[e[i].to],v.second=e[i].to;
PQ.push(v);
}
}
}
bool check(LL lim){
int tmp=,i,h=,t=;
int l,r,mid;
f[]=lin[]=,grt_st[]=;
que[t]=;
for(i=;i<=b;i++){
l=h+,r=t,mid=(l+r)>>;
while(r-l>){
if(i>=grt_st[que[mid]]) l=mid;
else r=mid-;
mid=(l+r)>>;
}
for(mid=r;mid>=l;mid--)
if(i>=grt_st[que[mid]]){
f[i]=ask(i,que[mid])+lim,lin[i]=lin[que[mid]]+;
break;
}
if(i==b) break;
grt_st[i]=b+;
while(h<t&&grt_st[que[t]]>i&&ask(grt_st[que[t]],i)<=ask(grt_st[que[t]],que[t])) grt_st[i]=grt_st[que[t]],t--;
if(h<t){
l=max(grt_st[que[t]],i+),r=grt_st[i]-,mid=(l+r)>>;
while(r-l>){
if(ask(mid,i)<=ask(mid,que[t])) r=mid;
else l=mid+;
mid=(l+r)>>;
}
for(mid=l;mid<=r;mid++)
if(ask(mid,i)<=ask(mid,que[t])){
grt_st[i]=mid;
break;
}
}
if(grt_st[i]!=b+)
que[++t]=i;
}
return lin[b]>=s;
}
LL ask(int x,int typ){
return f[typ]+(x-typ-)*(sum[x]-sum[typ]);
}
[World Final 2016] Branch Assignment的更多相关文章
- 4609: [Wf2016]Branch Assignment 最短路 DP (阅读理解题)
Bzoj的翻译出锅了所以来官方题面:这个题应该是单向边而BZOJ说的是双向边,什么你WA了?谁叫你懒得看英文...... 显然我们能正向反向两遍SPFA处理出每个点到总部的距离和总部到每个点的距离.如 ...
- Gym-101242B:Branch Assignment(最短路,四边形不等式优化DP)
题意:要完成一个由s个子项目组成的项目,给b(b>=s)个部门分配,从而把b个部门分成s个组.分组完成后,每一组的任 意两个点之间都要传递信息.假设在(i,j)两个点间传送信息,要先把信息加密, ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 4619 Swap Space 解题报告
今天是因为David Lee正好讲这个题的类似题,我才做了一下. 本题是world final 2016的一道水…… 题目地址如下 http://www.lydsy.com/JudgeOnline/p ...
- Kafka Consumer2
本文记录了和conumser相关的几个类. 首先是RequestFuture这个类,consumer和服务端通信使用它作为返回值. 其次是HeartBeat机制,consumer和coordinato ...
- JGit----将 Git 嵌入你的应用
如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit . JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用 ...
- 2016/09/21 Java关键字final
1.final类 final类不能被继承,没有子类,final类中的方法默认是final的. final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的. 2.final方 ...
- 2016 China Collegiate Programming Contest Final
2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...
- Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution
Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...
随机推荐
- D17——C语言基础学PYTHON
C语言基础学习PYTHON——基础学习D17 20181014内容纲要: 1.jQuery介绍 2.jQuery功能介绍 (1)jQuery的引入方式 (2)选择器 (3)筛选 (4)文本操作 (5) ...
- 架构模式数据源模式之:数据映射器(Data Mapper)
一:数据映射器 关系型数据库用来存储数据和关系,对象则可以处理业务逻辑,所以,要把数据本身和业务逻辑糅杂到一个对象中,我们要么使用 活动记录,要么把两者分开,通过数据映射器把两者关联起来. 数据映射器 ...
- Zookeeper配置文件中的配置项解释和Zookeeper的安装
zookeeper的默认配置文件为zookeeper/conf/zoo_sample.cfg,需要将其修改为zoo.cfg.其中各配置项的含义,解释如下: 1.tickTime:CS通信心跳时间Zoo ...
- (转)contextlib — 上下文管理器工具
原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...
- 业余实现一个统计A股数据工具
自己瞎捣鼓了几天 python,数据来源新浪财经,每天收盘启动爬虫抓取一遍,web 端呈现日线与周线数据:实时图表显示上证指数与个股指数等.技术点:scrapy apscheduler sqlalch ...
- 运行vue init webpack vueTest时报错
前言:好久没动vue项目了,早上心血来潮.准备写一个项目,然后坚持在github更新,不为别的,只为养成一个习惯. 运行vue init webpack vueTest时,报了下面的错误: 当时我思考 ...
- 单线程实现同时监听多个端口(windows平台c++代码)
前言 多年前开发了一套网络库,底层实现采用IOCP(完成端口).该库已在公司多个程序中应用:经过多次修改,长时间检验,已经非常稳定高效. 最近把以前的代码梳理了一下,又加进了一些新的思路.代码结构更加 ...
- zmq 三种模型的python实现
1.Request-Reply模式: 客户端在请求后,服务端必须回响应 server: #!/usr/bin/python #-*-coding:utf-8-*- import time import ...
- Linux系列:Ubuntu/fedora实用小技巧—禁止自动锁屏、设置免密码自动登录、免密码执行sudo操作
首先声明:该文虽以Ubuntu 13.04为例,同样适用于Fedora 17(已测试),但在较低版本的Ubuntu下可能有所差异,具体看后面的注意事项. 技巧目录: 解决Ubuntu下每隔几分钟自动锁 ...
- Linux系统修改防火墙配置
防火墙配置文件位置 /etc/sysconfig/iptables 需要开放端口,请在里面添加一条内容即可: 1 -A RH-Firewall-1-INPUT -m state --state NEW ...