链接

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. JAVA实现微信支付V3

    喜欢的朋友可以关注下,粉丝也缺. 相信很多的码友在项目中都需要接入微信支付,虽说微信支付已成为一个普遍的现象,但是接入的过程中难免会遇到各种各样的坑,这一点支付宝的SDK就做的很好,已经完成的都知道了 ...

  2. tkinter如何设置界面消失 当制作一个登陆界面时,登陆成功之后,如何让登陆界面本身消失

    tkinter如何设置界面消失 当制作一个登陆界面时,登陆成功之后,如何让登陆界面本身消失 if querySQL.checkAll():#用户名和密码都输入正确 self.root.withdraw ...

  3. 【xsy1130】tree 树形dp+期望dp

    题目写得不清不楚的... 题目大意:给你一棵$n$个节点的树,你会随机选择其中一个点作为根,随后随机每个点深度遍历其孩子的顺序. 下面给你一个点集$S$,问你遍历完$S$中所有点的期望时间,点集S中的 ...

  4. Handler 、 Looper 、Message异步消息处理线程机制( hander消息机制原理)

    Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念. 那么什么叫异步消息处理线程呢? 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次, ...

  5. Python:线程指南

    1. 线程基础 1.1. 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2. 线程同步(锁) 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样).但是当线程需要共享数据时,可能存在 ...

  6. Redis笔记(4)独立功能的实现

    1.前言 本节记录一下redis的一些功能上的实现,包括发布订阅.事务.Lua脚本.排序.二进制位数组.慢查询日志和监视器. 2.发布订阅 上一章介绍sentinel的时候说到了sentinel会订阅 ...

  7. list、vector、deque互相拷贝

    #include <iostream> #include <stdlib.h> #include <string.h> #include <algorithm ...

  8. 关于 ASP.NET Web 应用中 async/await 注意问题

    System.NullReferenceException: Object reference not set to an instance of an object. at System.Web.T ...

  9. php -- 正则替换

    ----- 019-regex_replace.php ----- <!DOCTYPE html> <html> <head> <meta http-equi ...

  10. 02 - JavaSE之基础及面向对象(补充)

    引用数据类型 java中的数据类型可以分为 基本数据类型 和 引用数据类型 两大类 int float char boolean等都是基本数据类型 类类型都是引用数据类型 引用数据类型类似C语言中的指 ...