链接

PDF

bzoj

先求出正置边和反置边时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的更多相关文章

  1. 4609: [Wf2016]Branch Assignment 最短路 DP (阅读理解题)

    Bzoj的翻译出锅了所以来官方题面:这个题应该是单向边而BZOJ说的是双向边,什么你WA了?谁叫你懒得看英文...... 显然我们能正向反向两遍SPFA处理出每个点到总部的距离和总部到每个点的距离.如 ...

  2. Gym-101242B:Branch Assignment(最短路,四边形不等式优化DP)

    题意:要完成一个由s个子项目组成的项目,给b(b>=s)个部门分配,从而把b个部门分成s个组.分组完成后,每一组的任 意两个点之间都要传递信息.假设在(i,j)两个点间传送信息,要先把信息加密, ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. BZOJ 4619 Swap Space 解题报告

    今天是因为David Lee正好讲这个题的类似题,我才做了一下. 本题是world final 2016的一道水…… 题目地址如下 http://www.lydsy.com/JudgeOnline/p ...

  5. Kafka Consumer2

    本文记录了和conumser相关的几个类. 首先是RequestFuture这个类,consumer和服务端通信使用它作为返回值. 其次是HeartBeat机制,consumer和coordinato ...

  6. JGit----将 Git 嵌入你的应用

    如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit . JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用 ...

  7. 2016/09/21 Java关键字final

    1.final类 final类不能被继承,没有子类,final类中的方法默认是final的. final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的. 2.final方 ...

  8. 2016 China Collegiate Programming Contest Final

    2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...

  9. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

随机推荐

  1. python实现音乐播放器

    python实现音乐播放器 模块:pygame 模块:time Python 布尔循环实例: import time import pygame muxi_k = """ ...

  2. 使用ServiceStack改造我们的项目

    ServiceStack是一个NET环境下的开源框架集合 包括轻量级的Orm框架,数据库访问,Json处理,Redis驱动等多个模块,我们可以按需选择使用 serviceStack.Ormlite s ...

  3. (转)Python中的上下文管理器和Tornado对其的巧妙应用

    原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...

  4. android开发学习——day1

    了解安卓系统架构:Linux内核层,系统运行层库,应用框架层,应用层 版本信息 android开发的特色之处就在于强大的组件功能 开发环境android stdio 2.0安装:把安装的组件都勾选上, ...

  5. 微信小程序交流群,欢迎加入,其中微信小程序开发群、Jenkins开发群是有问必答群

    微信小程序开发,请加群511389428,511389428 有问必答群:React开发,请加群523838207:523838207Jenkins开发,请加群155799363,155799363  ...

  6. JAVA框架之Spring【Spring事务详解】

    spring提供的事务管理可以分为两类:编程式的和声明式的.编程式的,比较灵活,但是代码量大,存在重复的代码比较多:声明式的比编程式的更灵活.编程式主要使用transactionTemplate.省略 ...

  7. 全网最详细的Sublime Text 3的激活(图文详解)

    不多说,直接上干货! 前期博客 全网最详细的Windows里下载与安装Sublime Text *(图文详解) ZYNGA INC. User License EA7E- 927BA117 84C93 ...

  8. 如何用R来处理数据表的长宽转换(图文详解)

    不多说,直接上干货! 很多地方都需用到这个知识点,比如Tableau里.   通常可以采取如python 和 r来作为数据处理的前期. Tableau学习系列之Tableau如何通过数据透视表方式读取 ...

  9. 【转】谷歌三大核心技术(二)Google MapReduce中文版

      Google MapReduce中文版     译者: alex   摘要 MapReduce 是一个编程模型,也是一个处理和生成超大数据集的算法模型的相关实现.用户首先创建一个Map函数处理一个 ...

  10. java Queue的用法

    https://www.cnblogs.com/caozengling/p/5307992.html https://blog.csdn.net/a724888/article/details/802 ...