【BZOJ】【3550】【ONTAK2010】Vacation
网络流/费用流
Orz太神犇了这题……
我一开始想成跟Intervals那题一样了……每个数a[i]相当于覆盖了(a[i]-n,a[i]+n)这个区间……但是这样是错的!!随便就找出反例了……我居然还一直当正解……
实际上刚刚那个思路还有一个问题:题目中的长度为N的区间指的是给的原序列!而不是权值的区间!题就理解错了……
看了下zyf的题解,才明白过来,要用跟志愿者招募一样的方法来做;另外,志愿者招募时每种志愿者是有无限多名的,但这题中每个数只能选一次,所以边权为a[i]的边的流量不能是INF,而是1。
题解:做这题真是一种折磨。。。复习了一下根据流量平衡方程建图的方法,主要是膜拜了byvoid的志愿者招募的题解。。。让我们先列出流量平衡方程:a[i]表示i选不选,b[i]表示第i个等式的辅助变量则:0=0a[1]+a[2]+……a[n]+b[1]=ka[2]+a[3]+……a[n+1]+b[2]=k…………a[2*n+1]+a[2*n+2]+……+a[3*n]+b[2*n+1]=k0=0差分之后是a[1]+a[2]+……a[n]+b[1]=ka[n+1]-a[1]+b[2]-b[1]=0a[n+2]-a[2]+b[3]-b[2]=0…………-a[2*n+1]-a[2*n+2]-………-a[3*n]-b[2*n+1]=-k根据BYVOID所说的这段话:可以发现,每个等式左边都是几个变量和一个常数相加减,右边都为0,恰好就像网络流中除了源点和汇点的顶点都满足流量平衡。每个正的变量相当于流入该顶点的流量,负的变量相当于流出该顶点的流量,而正常数可以看作来自附加源点的流量,负的常数是流向附加汇点的流量。因此可以据此构造网络,求出从附加源到附加汇的网络最大流,即可满足所有等式。而我们还要求最小,所以要在X变量相对应的边上加上权值,然后求最小费用最大流。
所以我们构图:s=0;t=3*n+1;
for1(i,3*n)a[i]=read();
insert(s,1,k,0);insert(2*n+2,t,k,0);
for1(i,n)insert(1,i+1,1,-a[i]);
for2(i,n+1,2*n)insert(i-n+1,i+1,1,-a[i]);
for2(i,2*n+1,3*n)insert(i-n+1,2*n+2,1,-a[i]);
for1(i,2*n+1)insert(i,i+1,inf,0);需要搞清楚a[i]在哪个等式中第一次出现,在哪个等式中第二次出现,以及正负号各是什么。
b[i]的出现很显然,i为正,i+1为负
然后求最大费用最大流就可以过了。
/**************************************************************
Problem: 3550
User: Tunix
Language: C++
Result: Accepted
Time:20 ms
Memory:6016 kb
****************************************************************/ //BZOJ 3550
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define CC(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
typedef long long LL;
const int N=,M=,INF=~0u>>;
const double eps=1e-;
/*******************template********************/
int n,m,k,a[N],b[N],c[N],w[N];
LL ans;
struct edge{int from,to,v,c;};
struct Net{
edge E[M];
int head[N],next[M],cnt;
void ins(int x,int y,int z,int c){
E[++cnt]=(edge){x,y,z,c};
next[cnt]=head[x]; head[x]=cnt;
}
void add(int x,int y,int z,int c){
ins(x,y,z,c); ins(y,x,,-c);
}
int S,T,d[N],from[N],Q[M];
bool inq[N];
bool spfa(){
int l=,r=-;
F(i,,T)d[i]=INF;
d[S]=; Q[++r]=S; inq[S]=;
while(l<=r){
int x=Q[l++]; inq[x]=;
for(int i=head[x];i;i=next[i])
if(E[i].v && d[x]+E[i].c<d[E[i].to]){
d[E[i].to]=d[x]+E[i].c;
from[E[i].to]=i;
if(!inq[E[i].to]){
Q[++r]=E[i].to;
inq[E[i].to]=;
}
}
}
return d[T]!=INF;
}
void mcf(){
int x=INF;
for(int i=from[T];i;i=from[E[i].from])
x=min(x,E[i].v);
for(int i=from[T];i;i=from[E[i].from]){
E[i].v-=x;
E[i^].v+=x;
}
ans+=x*d[T];
}
void init(){
m=n=getint(); m*=; k=getint(); cnt=;
F(i,,m) a[i]=getint();
S=; T=*n+;
add(S,,k,);
add(n*+,T,k,);
F(i,,n*+) add(i,i+,INF,); F(i,,n+) add(,i,,-a[i-]);
F(i,n+,*n+) add(i,*n+,,-a[i+n-]);
F(i,,n+) add(i,i+n,,-a[i+n-]); while(spfa()) mcf();
printf("%lld\n",-ans);
}
}G1;
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
G1.init();
return ;
}
3550: [ONTAK2010]Vacation
Time Limit: 10 Sec Memory Limit: 96 MB
Submit: 141 Solved: 105
[Submit][Status][Discuss]
Description
有3N个数,你需要选出一些数,首先保证任意长度为N的区间中选出的数的个数<=K个,其次要保证选出的数的个数最大。
Input
第一行两个整数N,K。
第二行有3N个整数。
Output
一行一个整数表示答案。
Sample Input
14 21 9 30 11 8 1 20 29 23 17 27 7 8 35
Sample Output
HINT
【数据范围】
N<=200,K<=10。
Source
【BZOJ】【3550】【ONTAK2010】Vacation的更多相关文章
- 【BZOJ 2754 喵星球上的点名】
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2512 Solved: 1092[Submit][Status][Discuss] Descript ...
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 【BZOJ】3319: 黑白树
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...
- 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...
- 【BZOJ】【1025】【SCOI2009】游戏
DP/整数拆分 整个映射关系可以分解成几个循环(置换群的预备知识?),那么总行数就等于各个循环长度的最小公倍数+1(因为有个第一行的1~N).那么有多少种可能的排数就等于问有多少种可能的最小公倍数. ...
- 【BZOJ】1013: [JSOI2008]球形空间产生器sphere
[BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...
- 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...
- 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang
点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...
- 【BZOJ】【3083】遥远的国度
树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...
- 【BZOJ】【2434】【NOI2011】阿狸的打字机
AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...
随机推荐
- 重拾C,一天一点点_11
命令行参数 在支持C语言的环境中,可以在程序开始执行时将命令行参数传递给程序. 调用主函数main时,它带有两个参数,第一个参数(argc,用于参数计数)的值表示运行程序时命令行参数的数目:第二个参数 ...
- 解决Genymotion下载设备失败的方法(Connection Timeout)
一直下载不下来,报错. 解决办法: 打开 C:\Users\用户名\AppData\Local\Genymobile目录 打开genymotion.log文件,在里面最下面几行,找到如下日志 [Deb ...
- 006-python基础-条件判断与循环
一.条件判断 场景一.用户登陆验证 # 提示输入用户名和密码 # 验证用户名和密码 # 如果错误,则输出用户名或密码错误 # 如果成功,则输出 欢迎,XXX! #!/usr/bin/env pytho ...
- iphone/ipad关于size, frame and bounds总结和UIScroll view学习笔记
1. iphone/ipad大小 Device Screen dimensions(in points) iphone and ipod 320 X 480 ipad 768 X 1024 2. UI ...
- Objective-C关于数据处理
本文介绍如何在Objective-C中操作数据.我们将使用数组.指针.字符串等. 数组是数据项的一个集合,这些数据项叫做元素,我们可以用一个数组索引来引用元素.例如,如果把数字存储在一个名为array ...
- 分布式缓存Memcached
分布式缓存服务器,既然用到数据缓存很明显就是想高效性的获取数据,大容量的存储数据.为了可以缓存大量的数据以及可以高效获取数据,那么分布式缓存数据库就要解决数据可以水平线性扩展,这样可以扩大数据容 ...
- RTP、RTCP
http://blog.chinaunix.net/uid-22670933-id-1771676.html
- 怎么解决/bin/sh: arm-linux-gcc: not found make
1.arm-linux-gcc 环境变量没有设,所以找不到这个编译器 在/etc/profile里添加arm-linux-gcc的存放路径 sudo -s gedit /etc/profile 编 ...
- AOP在 .NET中的七种实现方法
7Approaches for AOP in .Net AOP在 .NET中的七种实现方法 Here are all the ways that I can think of to add AOPto ...
- iOS学习之C语言数据类型
1.进制 0 1 2 3 4 5 6 7 8 9 A B C D E F 0X123(十六进制) 0123(八进制) 位权:单位数字的基本数值 2.数据类型 关键字 说明 字节大小 char ...
