UOJ#77. A+B Problem
题目名称是吸引你点进来的。
从前有个 n 个方格排成一行,从左至右依此编号为 1,2,⋯,n。
有一天思考熊想给这 n 个方格染上黑白两色。
第 i 个方格上有 6 个属性:ai,bi,wi,li,ri,pi。
如果方格 i 染成黑色就会获得 bi 的好看度。
如果方格 i 染成白色就会获得 wi 的好看度。
但是太多了黑色就不好看了。如果方格 i 是黑色,并且存在一个 j 使得 1≤j<i 且 li≤aj≤ri 且方格 j 为白色,那么方格 i 就被称为奇怪的方格。
如果方格 i 是奇怪的方格,就会使总好看度减少 pi。
也就是说对于一个染色方案,好看度为:
现在给你 n,a,b,w,l,r,p,问所有染色方案中最大的好看度是多少。
输入格式
第一行一个正整数 n。
接下来 n 行中第 i 行有用空格隔开的 6 个非负整数依次表示 ai,bi,wi,li,ri,pi。
保证 li≤ri。
输出格式
一个非负整数表示所有染色方案中最大的好看度。
样例一
input
10
0 1 7 3 9 2
7 4 0 9 10 5
1 0 4 2 10 2
7 9 1 5 7 2
6 3 5 3 6 2
6 6 4 1 8 1
6 1 6 0 6 5
2 2 5 0 9 3
5 1 3 0 2 5
5 6 7 1 1 2
output
55
explanation
最优染色方案为:白 黑 白 黑 白 黑 白 白 白 白
可以发现只有方格 6 为奇怪的方格。
所以好看度为:
限制与约定
设 amax 为 a,l,r 中的最大值,vmax 为 b,w 中的最大值, pmax 为 p 中的最大值。
测试点编号 | n | amax | vmax | pmax |
---|---|---|---|---|
1 | =5 | ≤10 | ≤10 | ≤10 |
2 | =20 | ≤40 | ≤40 | ≤40 |
3 | =20 | ≤40 | ≤40 | ≤40 |
4 | =5000 | ≤10 | ≤200000 | ≤100000 |
5 | =5000 | ≤10 | ≤200000 | ≤300000 |
6 | =200 | ≤109 | ≤200000 | ≤200000 |
7 | =300 | ≤109 | ≤200000 | ≤220000 |
8 | =500 | ≤109 | ≤200000 | ≤400000 |
9 | =5000 | ≤5000 | ≤200000 | ≤150000 |
10 | =5000 | ≤109 | ≤200000 | ≤300000 |
时间限制:2s
空间限制:48MB
来源
VFleaKing
看WZJ这蒟蒻卡爆测评机2333333
都在这里了http://oj.cnuschool.org.cn/oj/home/educationArchiveList.htm A+B,登陆后下载
由于我现推的,和VFK论文中的写的正好相反。
暴力:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxm=;
struct Dinic {
int n,m,s,t,nowd;
int vis[maxn],d[maxn],cur[maxn],first[maxn],next[maxm];
struct Edge {int from,to,flow;}edges[maxm];
void init(int n) {
this->n=n;m=;
fill(first+,first+n+,-);
}
void AddEdge(int u,int v,int w) {
edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++;
edges[m]=(Edge){v,u,};next[m]=first[v];first[v]=m++;
}
int BFS() {
queue<int> Q;
Q.push(s);d[s]=;vis[s]=++nowd;
while(!Q.empty()) {
int x=Q.front();Q.pop();cur[x]=first[x];
ren {
Edge& e=edges[i];
if(e.flow&&vis[e.to]!=nowd) {
vis[e.to]=nowd;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t]==nowd;
}
int DFS(int x,int a) {
if(x==t||!a) return a;
int flow=,f;
for(int& i=cur[x];i!=-;i=next[i]) {
Edge& e=edges[i];
if(d[e.to]==d[x]+&&(f=DFS(e.to,min(e.flow,a)))) {
flow+=f;a-=f;
e.flow-=f;edges[i^].flow+=f;
if(!a) break;
}
}
return flow;
}
int solve(int s,int t) {
this->s=s;this->t=t;
int flow=;
while(BFS()) flow+=DFS(s,1e9);
return flow;
}
}sol;
int n,a[maxn],b[maxn],w[maxn],l[maxn],r[maxn],p[maxn];
void solve() {
int S=*n+,T=*n+,all=;sol.init(T);
rep(,n) sol.AddEdge(S,i,w[i]),sol.AddEdge(i,T,b[i]),all+=w[i]+b[i];
rep(,n) {
for(int j=;j<i;j++) if(l[i]<=a[j]&&a[j]<=r[i]) sol.AddEdge(j,i+n,1e9);
sol.AddEdge(i+n,i,p[i]);
}
printf("%d\n",all-sol.solve(S,T));
}
int main() {
n=read();
rep(,n) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
solve();
return ;
}
正解:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<queue>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
const int maxm=;
struct Dinic {
int n,m,s,t,nowd;
int vis[maxn],d[maxn],cur[maxn],first[maxn],next[maxm];
struct Edge {int from,to,flow;}edges[maxm];
void init() {
m=;
memset(first,-,sizeof(first));
}
void AddEdge(int u,int v,int w) {
if(!u||!v) return;
edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++;
edges[m]=(Edge){v,u,};next[m]=first[v];first[v]=m++;
}
int BFS() {
queue<int> Q;
Q.push(s);d[s]=;vis[s]=++nowd;
while(!Q.empty()) {
int x=Q.front();Q.pop();cur[x]=first[x];
ren {
Edge& e=edges[i];
if(e.flow&&vis[e.to]!=nowd) {
vis[e.to]=nowd;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t]==nowd;
}
int DFS(int x,int a) {
if(x==t||!a) return a;
int flow=,f;
for(int& i=cur[x];i!=-;i=next[i]) {
Edge& e=edges[i];
if(d[e.to]==d[x]+&&(f=DFS(e.to,min(e.flow,a)))) {
flow+=f;a-=f;
e.flow-=f;edges[i^].flow+=f;
if(!a) break;
}
}
return flow;
}
int solve(int s,int t) {
this->s=s;this->t=t;
int flow=;
while(BFS()) flow+=DFS(s,1e9);
return flow;
}
}sol;
int n,a[],b[],w[],l[],r[],p[];
int root[maxn],ls[maxn],rs[maxn],ToT;
void build(int& y,int x,int l,int r,int pos,int v) {
y=++ToT;
if(l==r) {
if(x) sol.AddEdge(x,y,1e9);
sol.AddEdge(v,y,1e9);
return;
}
int mid=l+r>>;ls[y]=ls[x];rs[y]=rs[x];
if(pos<=mid) build(ls[y],ls[x],l,mid,pos,v);
else build(rs[y],rs[x],mid+,r,pos,v);
if(ls[y]) sol.AddEdge(ls[y],y,1e9);
if(rs[y]) sol.AddEdge(rs[y],y,1e9);
}
void query(int y,int l,int r,int ql,int qr,int v) {
if(!y) return;
if(ql<=l&&r<=qr) {sol.AddEdge(y,v,1e9);return;}
int mid=l+r>>;
if(ql<=mid) query(ls[y],l,mid,ql,qr,v);
if(qr>mid) query(rs[y],mid+,r,ql,qr,v);
}
int tmp[],cnt;
void pre() {
int m=;
rep(,n) tmp[++m]=a[i],tmp[++m]=l[i],tmp[++m]=r[i];
sort(tmp+,tmp+m+);cnt=m;
rep(,n) a[i]=lower_bound(tmp+,tmp+m+,a[i])-tmp;
rep(,n) l[i]=lower_bound(tmp+,tmp+m+,l[i])-tmp;
rep(,n) r[i]=lower_bound(tmp+,tmp+m+,r[i])-tmp;
}
void solve() {
int S=*n+,T=*n+,all=;sol.init();ToT=T;
rep(,n) sol.AddEdge(S,i,w[i]),sol.AddEdge(i,T,b[i]),all+=w[i]+b[i];
rep(,n) {
query(root[i],,cnt,l[i],r[i],i+n);
sol.AddEdge(i+n,i,p[i]);build(root[i+],root[i],,cnt,a[i],i);
}
printf("%d\n",all-sol.solve(S,T));
}
int main() {
n=read();
rep(,n) a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
pre();solve();
return ;
}
UOJ#77. A+B Problem的更多相关文章
- UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]
UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...
- BZOJ 3218 UOJ #77 A+B Problem (主席树、最小割)
大名鼎鼎的A+B Problem, 主席树优化最小割-- 调题死活调不对,一怒之下改了一种写法交上去A了,但是改写法之后第4,5个点常数变大很多,于是喜提UOJ全站倒数第三 目前还不知道原来的写法为什 ...
- BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)
竟然在BZOJ上拿了Rank1太给力啦. p.s.:汗,一发这个就被一堆人在2月27号强势打脸-- 传送门(BZOJ) 传送门(UOJ) 说说这道题目吧: 首先是说说这个构图吧.因为有选择关系,我们很 ...
- 【BZOJ3218】【UOJ#77】a + b Problem
题目 题目在这里 思路&做法 明显的最小割(其实是之前做过一道类似的题) S向每一个格子连容量为\(b_i\)的边 每一个格子向T连容量为\(w_i\)的边 对于格子\(i\)向满足条件的格子 ...
- 【UOJ#77】A+B Problem
传送门 题目描述 略 Sol 看到选择黑白收益不同,然后还可能有代价. 我们想到用网络流解决,并且这应该是用总可能收益-最小割得到答案. 考虑初步建图,发现那个限制可以直接 \(n^2\) 解决. 我 ...
- UOJ#XX A+B Problem (罔烙硫)
题面 背景 题目描述 从前有个 n n n 个方格排成一行,从左至右依此编号为 1 , 2 , ⋯ , n 1,2,⋯,n 1,2,⋯,n. 有一天思考熊想给这 n n n 个方格染上黑白两色. 第 ...
- 【UOJ #246】【UER #7】套路
http://uoj.ac/contest/35/problem/246 神奇!我这辈子是想不出这样的算法了. 对区间长度分类讨论:题解很好的~ 我已经弱到爆了,看完题解后还想了一晚上. 题解中&qu ...
- 【UOJ #244】【UER #7】短路
http://uoj.ac/contest/35/problem/244 对其他人来说好简单的一道题,我当时却不会做TWT 注定滚粗啊 题解很好的~ #include<cstdio> #i ...
- UOJ 180【UR #12】实验室外的攻防战
http://uoj.ac/contest/25/problem/180 从前往后对比串A,B 当$A_i,B_i$不相同时找到$B_i$在A中的位置j 若$min{A_1,A_2,A_3...... ...
随机推荐
- 【GoLang】GoLang 微服务、开源库等参考资料
参考资料: GoLang书籍: https://github.com/dariubs/GoBooksGo名库: https://github.com/Unknwon/go-rock-libraries ...
- Recover Rotated Sorted Array
Given a rotated sorted array, recover it to sorted array in-place. Clarification What is rotated arr ...
- Android 中获得notification的发出时间
最近做程序时,有一个类似闹钟的功能,用notification唤醒程序后,希望能得到发出这个notification时的具体时间,就是notification右边写着的那个时间.查了notificat ...
- Extjs的数据读取器store和后台返回类型简单解析
工作中用到了Extjs,从后台获取数据的时候,用到了extjs自己的Ext.data.store方法,然后封装了ExtGridReturn方法, 目的:前台用到Ext.data.store读取从后台传 ...
- Intellj IDEA快捷键
Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码 ...
- [MAC ] Mac-OSX下安装Git
转载自 : http://www.cnblogs.com/shanyou/archive/2011/01/30/1948088.html Mac-OSX下安装Git是一件很简单的事,我们可以下载一个安 ...
- 爱改名的小融 2(codevs 3149)
3149 爱改名的小融 2 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description Wikioi上有个人 ...
- .net学习笔记----会话状态Session
一.会话状态Session Session用于服务器端状态管理,使用Session之后,每个客户端都可以将实际的数据保存在服务器上,对于每个客户端的数据,将会生成一个对应的唯一的key(保存在客户端) ...
- Python语言开发的一些问题
1.Python是如何进行内存管理的? Python引用了一个内存池(memory pool)机制,即Pymalloc机制(malloc:n.分配内存),用于管理对小块内存的申请和释放内存池(memo ...
- Oracle 11g必须开启的服务及服务详细介绍(转)
成功安装Oracle 11g数据库后,你会发现自己电脑运行速度会变慢,配置较低的电脑甚至出现非常卡的状况,通过禁止非必须开启的Oracle服务可以提升电脑的运行速度.那么,具体该怎么做呢? 按照win ...