标签:style eof space i++ += const bfs 约束 cond
$\newcommand{\edge}[1]{\mathop\rightarrow\limits^{#1}}$先取所有$b_i,w_i$,然后建图跑最小割
要么割$w_i$要么割$b_i$,所以这两条边必须相连,初步的想法是这样:

如果割了$w_i$并且存在题目所说的$j$,那么我们还要割掉$p_i$,所以不妨拆点,构造一条$j\edge{\infty}i‘\edge{p_i}i\edge{b_i}T$的路径,不难发现如果割掉了$w_i$则必然割掉$p_i$

直接建图,边数是$O(n^2)$的,空间太大,所以要优化建图
约束是$a_j\in[l_i,r_i]$的形式,我们可以建一棵线段树,儿子向父亲连边,把$j$连到线段树中对应下标的叶子节点,并且把$[l_i,r_i]$这个区间在线段树中的对应节点连向$i‘$就可以了
这样做并没有考虑$j\lt i$这个约束,把线段树可持久化就可以加上这个约束了,对应的连边也要“可持久化”,即加入指向新节点的边,本来对于新建的链,原线段树中与这条链重复的所有节点都要向新节点连边,但因为我们在新链上自底向上连边,所以只需把原来的叶子节点连到新的叶子节点即可
#include<stdio.h>
#include<string.h>
#include<map>
using namespace std;
const int inf=2147483647;
int h[200010],cur[200010],nex[1000010],to[1000010],cap[1000010],dis[200010],q[1000010],M=1,S,T;
void add(int a,int b,int c){
M++;
to[M]=b;
cap[M]=c;
nex[M]=h[a];
h[a]=M;
M++;
to[M]=a;
cap[M]=0;
nex[M]=h[b];
h[b]=M;
}
bool bfs(){
int head,tail,x,i;
memset(dis,-1,sizeof(dis));
head=tail=1;
q[1]=S;
dis[S]=0;
while(head<=tail){
x=q[head];
head++;
for(i=h[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==-1){
dis[to[i]]=dis[x]+1;
if(to[i]==T)return 1;
tail++;
q[tail]=to[i];
}
}
}
return 0;
}
int dfs(int x,int flow){
if(x==T)return flow;
int i,f;
for(i=cur[x];i;i=nex[i]){
if(cap[i]&&dis[to[i]]==dis[x]+1){
f=dfs(to[i],min(flow,cap[i]));
if(f){
cap[i]-=f;
cap[i^1]+=f;
if(cap[i])cur[x]=i;
return f;
}
}
}
dis[x]=-1;
return 0;
}
int dicnic(){
int ans=0,tmp;
while(bfs()){
memcpy(cur,h,sizeof(h));
while(tmp=dfs(S,inf))ans+=tmp;
}
return ans;
}
struct seg{
int l,r;
}t[1000010];
int C,n;
int tr(int x){return x+2*(n+1);}
void insert(int&nr,int pr,int p,int v,int l,int r){
nr=++C;
t[nr]=t[pr];
if(l==r){
if(pr)add(tr(pr),tr(nr),inf);
return add(v,tr(nr),inf);
}
int mid=(l+r)>>1;
if(p<=mid)
insert(t[nr].l,t[pr].l,p,v,l,mid);
else
insert(t[nr].r,t[pr].r,p,v,mid+1,r);
if(t[nr].l)add(tr(t[nr].l),tr(nr),inf);
if(t[nr].r)add(tr(t[nr].r),tr(nr),inf);
}
void modify(int L,int R,int v,int l,int r,int x){
if(x==0)return;
if(L<=l&&r<=R)return add(tr(x),v,inf);
int mid=(l+r)>>1;
if(L<=mid)modify(L,R,v,l,mid,t[x].l);
if(mid<R)modify(L,R,v,mid+1,r,t[x].r);
}
map<int,int>pos;
map<int,int>::iterator it;
int a[5010],l[5010],r[5010],rt[5010];
int main(){
int N,i,b,w,p,s;
scanf("%d",&n);
S=n*2+1;
T=n*2+2;
s=0;
for(i=1;i<=n;i++){
scanf("%d%d%d%d%d%d",a+i,&b,&w,l+i,r+i,&p);
s+=b+w;
add(S,i,w);
add(i,T,b);
add(i+n,i,p);
pos[a[i]]=pos[l[i]]=pos[r[i]]=1;
}
N=0;
for(it=pos.begin();it!=pos.end();it++)it->second=++N;
for(i=1;i<=n;i++){
modify(pos[l[i]],pos[r[i]],i+n,1,N,rt[i-1]);
insert(rt[i],rt[i-1],pos[a[i]],i,1,N);
}
printf("%d",s-dicnic());
}
标签:style eof space i++ += const bfs 约束 cond
原文地址:https://www.cnblogs.com/jefflyy/p/8908436.html