【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=3218

【题意】

给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在:

1<=j<I,li<=aj<=ri,格子为白色

则损失pi,问最大的好看度。

【思路】

考虑建立最小割模型:

  1. 首先将一个点拆成两个中间连pi
  2. 连边(S,Xi,wi) (Xi,T,bi)
  3. 对于一个满足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(最小割+主席树)的更多相关文章

  1. BZOJ3218 UOJ#77 A+B Problem(最小割+主席树)

    竟然在BZOJ上拿了Rank1太给力啦. p.s.:汗,一发这个就被一堆人在2月27号强势打脸-- 传送门(BZOJ) 传送门(UOJ) 说说这道题目吧: 首先是说说这个构图吧.因为有选择关系,我们很 ...

  2. 【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 ...

  3. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  4. bzoj3218 a+b Problem(最小割+主席树优化建边)

    由于6.22博主要学测,大半时间学文化课,近期刷题量&写题解的数量会急剧下降. 这题出得挺经典的,首先一眼最小割,考虑朴素的做法:与S联通表示白色,与T联通表示黑色,S向i连流量为w[i]的边 ...

  5. BZOJ 3218 A + B Problem (可持久化线段树+最小割)

    做法见dalao博客 geng4512的博客, 思路就是用线段树上的结点来进行区间连边.因为有一个只能往前面连的限制,所以还要可持久化.(duliu) 一直以来我都是写dinicdinicdinic做 ...

  6. [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】

    题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...

  7. 【BZOJ-3218】a+b Problem 最小割 + 可持久化线段树

    3218: a + b Problem Time Limit: 20 Sec  Memory Limit: 40 MBSubmit: 1320  Solved: 498[Submit][Status] ...

  8. [BZOJ 3218]a + b Problem

    又是一道主席树优化网络流的好题 按约大爷的教导,源点为白,汇点为黑,搞成最小割 发现暴力连边要爆炸,但是要连的点在线段树中都构成了一个区间,果断主席树优化之 为什么不用一般线段树? 因为要满足 j&l ...

  9. BZOJ 2007 海拔(平面图最小割-最短路)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点 ...

随机推荐

  1. HTML5入门2---js获取HTML元素的值

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. shell脚本 -d 是目录文件,那么-e,-f等说明

    -e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L fil ...

  3. windows下python脚本程序的运行

    c:\python33\python.exe c:\python33\trycoding.py

  4. 车牌识别LPR系统系列文章汇总

    这里的LPR的的几篇文章是之前项目的一些相关资料的整理,涉及实验室内部的资料就没有放上来,希望能对想了解这方面的同学,有所帮助,那怕了解个大概也好.知道整体的思路就好.当初就是一个人瞎摸索,走了很多的 ...

  5. Windows 7下配置JDK环境变量

    安装jdk1.8版本(下载链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) ...

  6. Ubuntu中MySQL中文乱码解决

    1.以root登陆,在终端输入命令 sudo gedit /etc/mysql/my.cnf在打开的文件中找到[client]在下面加入default-character-set=utf8 找到 [m ...

  7. 新浪实时股票数据接口http://hq.sinajs.cn/list=code

    股票数据的获取目前有如下两种方法可以获取:1. http/javascript接口取数据2. web-service接口 1.http/javascript接口取数据1.1Sina股票数据接口以大秦铁 ...

  8. Unity 教程和源码

    12个Unity3D游戏源码 -  新手必备 愤怒的小鸟攻略技巧秘籍 NGUI 教程收录大全:http://forum.exceedu.com/forum/forum.php?mod=viewthre ...

  9. C结构体之位域(位段)

    C结构体之位域(位段) 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C ...

  10. LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

    题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他 ...