【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 ...
随机推荐
- MapReduce框架Partitioner分区方法
前言:对于二次排序相信大家也是似懂非懂,我也是一样,对其中的很多方法都不理解诶,所有只有暂时放在一边,当你接触到其他的函数,你知道的越多时你对二次排序的理解也就更深入了,同时建议大家对wordcoun ...
- WordPress 主题开发 - (七) 让主题更安全 待翻译
We're just about ready to start building our theme's template files. Before we do this, however, it' ...
- PHP file_get_contents于curl性能效率比较
说明大部分内容整理来源于网络,期待你的补充.及不当之处的纠正: 1)fopen/file_get_contents 每次请求远程URL中的数据都会重新做DNS查询,并不对DNS信息进行缓存.但是CUR ...
- 关于js中this的疑问
学习bootstrap.js源码中被js里边的this绕的有点晕 /* ================================================================ ...
- shell脚本调用spark-sql
为了更方便的查询并产生报表, 需要使用shell脚本调用spark-sql spark/bin/spark-sql --master spark://host:7077 -f ${SQL_FILE} ...
- 实战Django:官方实例Part5
俗话说,人非圣贤,孰能无过.在堆代码的过程中,即便是老攻城狮,也会写下一些错误的内容.俗话又说,过而能改,善莫大焉.要改,首先要知道哪里存在错误,这便是我们要对投票应用进行测试的原因. 21.撰写 ...
- [笔记]--Python字符串处理
一.截取字符串中的内容 1.截取: MsiExec.exe /I{AC76BA86-7AD7-2052-7B44-AB0000000001} 中的: {AC76BA86-7AD7-2052-7B44- ...
- main函数的argc和argv
int main(int argc, char const *argv[]) { printf("argc : %c\n",argc); printf(] ); printf( ...
- DOS通讯录
#include"stdio.h" #include"string.h" #include"stdlib.h" FILE *fp; #def ...
- 利用HttpModule开发asp.net页面、ashx等访问时session失效的统一处理入口
web程序时,当使用session时总会出现失效而报“未将对象引用设置到对象的实例”的http 500错误,本人比较懒,不想每个地方都用try catch处理,就找到个用httpModule统一处理的 ...
