bzoj 3218 a + b Problem(最小割+主席树)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3218
【题意】
给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在:
1<=j<I,li<=aj<=ri,格子为白色
则损失pi,问最大的好看度。
【思路】
考虑建立最小割模型:
- 首先将一个点拆成两个中间连pi
- 连边(S,Xi,wi) (Xi,T,bi)
- 对于一个满足i要求的j,连边(Xj,Yi,inf),代表i只有两种选择,一为设白色,一为损失pi。
这样跑出的最小割即为答案。
但该图的边数过多,因此需要优化。
建一棵线段树,由线段树中所有被[li,ri]包含的点向Yi连边inf,由Xi向对应的叶子连边。然后加上j<i的条件,我们需要一棵可持久化线段树,因此需要Yi被T[i-1]的[li,ri]区间连边,Xi向T[i]的叶子连边。这样就成功将边数缩到O(nlogn)级别。
【代码】
#include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define X(i) (i)
#define Y(i) (i+n)
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 2e5+;
const int inf = 1e9; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int u,v,cap,flow;
};
struct Dinic {
int d[N],cur[N],vis[N];
vector<Edge> es;
vector<int> g[N];
queue<int> q; void AddEdge (int u,int v,int w) {
es.push_back((Edge){u,v,w,});
es.push_back((Edge){v,u,,});
int m=es.size();
g[u].push_back(m-);
g[v].push_back(m-);
}
bool bfs(int s,int t) {
memset(vis,,sizeof(vis));
d[s]=; vis[s]=;
q.push(s);
while(!q.empty()) {
int u=q.front(); q.pop();
FOR(i,,(int)g[u].size()-) {
Edge& e=es[g[u][i]];
int v=e.v;
if(e.cap>e.flow&&!vis[v]) {
vis[v]=;
d[v]=d[u]+;
q.push(v);
}
}
}
return vis[t];
}
int dfs(int u,int a,int t) {
if(u==t||a==) return a;
int flow=,f;
for(int& i=cur[u];i<g[u].size();i++) {
Edge& e=es[g[u][i]];
int v=e.v;
if(d[v]==d[u]+&&(f=dfs(v,min(a,e.cap-e.flow),t))>) {
e.flow+=f;
es[g[u][i]^].flow-=f;
flow+=f,a-=f;
if(!a) break;
}
}
return flow;
}
int maxflow(int s,int t) {
int flow=;
while(bfs(s,t)) {
memset(cur,,sizeof(cur));
flow+=dfs(s,inf,t);
}
return flow;
}
} dc; int n,cnt; struct Tnode {
Tnode *ls,*rs;
int sum,id;
void * operator new (size_t,Tnode* l,Tnode* r) {
static Tnode mempool[N],*G=mempool;
G->ls=l,G->rs=r,G->id=++cnt;
return G++;
}
Tnode* build(int l,int r,int x,int from) {
int mid=l+r>>;
Tnode *t;
if(l==r)
t=new (0x0,0x0)Tnode;
else if(x<=mid)
t=new (ls->build(l,mid,x,from),rs) Tnode;
else
t=new (ls,rs->build(mid+,r,x,from)) Tnode;
dc.AddEdge(from,t->id,inf);
dc.AddEdge(id,t->id,inf);
return t;
}
void Add(int l,int r,int L,int R,int to) {
if(L<=l&&r<=R) {
dc.AddEdge(id,to,inf);
} else {
int mid=l+r>>;
if(L<=mid&&ls) ls->Add(l,mid,L,R,to);
if(mid<R&&rs) rs->Add(mid+,r,L,R,to);
}
} } *T[]; int hash[N],tot,a[N],b[N],l[N],r[N],p[N],w[N]; int main()
{
n=read();
cnt=Y(n);
int s=++cnt,t=++cnt;
T[]=new (0x0,0x0)Tnode;
T[]->ls=T[]->rs=T[];
ll ans=;
FOR(i,,n) {
a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
hash[++tot]=a[i],hash[++tot]=l[i],hash[++tot]=r[i];
} sort(hash+,hash+tot+);
tot=unique(hash+,hash+tot+)-hash-;
FOR(i,,n) {
a[i]=lower_bound(hash+,hash+tot+,a[i])-hash;
l[i]=lower_bound(hash+,hash+tot+,l[i])-hash;
r[i]=lower_bound(hash+,hash+tot+,r[i])-hash;
} FOR(i,,n) {
ans+=w[i]+b[i];
dc.AddEdge(s,X(i),w[i]);
dc.AddEdge(X(i),t,b[i]);
T[i]=T[i-]->build(,tot,a[i],X(i));
T[i-]->Add(,tot,l[i],r[i],Y(i));
dc.AddEdge(Y(i),X(i),p[i]);
}
ans-=dc.maxflow(s,t);
printf("%lld\n",ans);
return ;
}
P.S.神的我无力吐槽=-=
bzoj 3218 a + b Problem(最小割+主席树)的更多相关文章
- BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)
竟然在BZOJ上拿了Rank1太给力啦. p.s.:汗,一发这个就被一堆人在2月27号强势打脸-- 传送门(BZOJ) 传送门(UOJ) 说说这道题目吧: 首先是说说这个构图吧.因为有选择关系,我们很 ...
- 【bzoj3218】a+b Problem 最小割+主席树
数据范围:$n≤5000$,$a,l,r≤10^9$,$b,w,p≤2\times 10^5$. 我们考虑一种暴力的最小割做法: 首先令$sum=\sum\limits_{i=1}^{n} b_i+w ...
- BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)
BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...
- bzoj3218 a+b Problem(最小割+主席树优化建边)
由于6.22博主要学测,大半时间学文化课,近期刷题量&写题解的数量会急剧下降. 这题出得挺经典的,首先一眼最小割,考虑朴素的做法:与S联通表示白色,与T联通表示黑色,S向i连流量为w[i]的边 ...
- BZOJ 3218 A + B Problem (可持久化线段树+最小割)
做法见dalao博客 geng4512的博客, 思路就是用线段树上的结点来进行区间连边.因为有一个只能往前面连的限制,所以还要可持久化.(duliu) 一直以来我都是写dinicdinicdinic做 ...
- [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】
题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...
- 【BZOJ-3218】a+b Problem 最小割 + 可持久化线段树
3218: a + b Problem Time Limit: 20 Sec Memory Limit: 40 MBSubmit: 1320 Solved: 498[Submit][Status] ...
- [BZOJ 3218]a + b Problem
又是一道主席树优化网络流的好题 按约大爷的教导,源点为白,汇点为黑,搞成最小割 发现暴力连边要爆炸,但是要连的点在线段树中都构成了一个区间,果断主席树优化之 为什么不用一般线段树? 因为要满足 j&l ...
- BZOJ 2007 海拔(平面图最小割-最短路)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点 ...
随机推荐
- Android:文件夹显示红色叹号
有感叹号,说明有的文件损坏或丢失了 解决方法: 右击工程,Build Path..->Configure Build Path...->Java Build Path 可以看到引用的jar ...
- Spring3 报org.aopalliance.intercept.MethodInterceptor问题解决方法
原文:Spring3 报org.aopalliance.intercept.MethodInterceptor问题解决方法 一 开发环境:JDK5+Spring3.0.5+Myeclipse6.6+T ...
- 7、单向一对多的关联关系(1的一方有n的一方的集合属性,n的一方却没有1的一方的引用)
单向一对多的关联关系 具体体现:1的一方有n的一方的集合的引用,n的一方却没有1的一方的引用 举个例子:顾客Customer对订单Order是一个单向一对多的关联关系.Customer一方有对Orde ...
- PCL—低层次视觉—点云分割(最小割算法)
1.点云分割的精度 在之前的两个章节里介绍了基于采样一致的点云分割和基于临近搜索的点云分割算法.基于采样一致的点云分割算法显然是意识流的,它只能割出大概的点云(可能是杯子的一部分,但杯把儿肯定没分割出 ...
- Java API —— HashMap类 & LinkedHashMap类
1.HashMap类 1)HashMap类概述 键是哈希表结构,可以保证键的唯一性 2)HashMap案例 HashMap<String,String> ...
- weblogic11g 安装集群 —— win2003 系统、单台主机
weblogic11g 安装集群 —— win2003 系统.单台主机 注意:此为weblogic11g 在win2003系统下(一台主机)的安装集群,linux.hpux.aix及多个主机下原理一 ...
- How to upgrade boost libary using apt-get ?
apt-get install libboost1.55-all-dev using version number between boost and all, but the preconditio ...
- 【C#设计模式——创建型模式】抽象工厂模式
抽象工厂模式比工厂模式具有更高层次的抽象性.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以选择这种模式.直接进入示例. 示例描述:完成花园的规划,多种花园种类,每个里面多种 ...
- C#获取本机IP以及无线网ip
1 private void GetIP() 2 { 3 string hostName = Dns.GetHostName();//本机名 4 //System.Net.IPAddress ...
- $.toJSON的用法或把数组转换成json类型
1. html页面全部代码 <html> <head> <title></title> <script src="../../S ...