【BZOJ3218】a + b Problem(网络流)

思路跟 happiness 差不多,只不过需要用主席树优化一下建图。

#include<bits/stdc++.h>

#define N 5010
#define INF 0x7fffffff

using namespace std;

int read()
{
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x;
}

struct data
{
	int a,b,w,l,r,p;
}a[N];

struct Tree
{
	int lc,rc;
}t[100010];

int n,sum,S,T;
int tot,b[N*3];
int node,root[N];
int cnt=1,head[200010],cur[200010],to[2000010],nxt[2000010],c[2000010];
int num[200010];

queue<int>q;

void adde(int u,int v,int ci)
{
	to[++cnt]=v;
	c[cnt]=ci;
	nxt[cnt]=head[u];
	head[u]=cnt;
	
	to[++cnt]=u;
	c[cnt]=0;
	nxt[cnt]=head[v];
	head[v]=cnt;
}

void build(int &u,int l,int r)
{
	u=++node;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(t[u].lc,l,mid);
	build(t[u].rc,mid+1,r);
	adde(T+u,T+t[u].lc,INF);
	adde(T+u,T+t[u].rc,INF);
}

void update(int last,int &u,int l,int r,int x,int id)
{
	u=++node;
	adde(T+u,1+id,INF);
	if(l==r)
	{	
		if(last) adde(T+u,T+last,INF);
		return;
	}
	int mid=(l+r)>>1;
	t[u]=t[last];
	if(x<=mid) update(t[last].lc,t[u].lc,l,mid,x,id);
	else update(t[last].rc,t[u].rc,mid+1,r,x,id);
	if(t[u].lc) adde(T+u,T+t[u].lc,INF);
	if(t[u].rc) adde(T+u,T+t[u].rc,INF);
}

void query(int u,int l,int r,int ql,int qr,int newnode)
{
	if(!u) return;
	if(ql<=l&&r<=qr)
	{
		adde(newnode,T+u,INF);
		return;
	}
	int mid=(l+r)>>1;
	if(ql<=mid) query(t[u].lc,l,mid,ql,qr,newnode);
	if(qr>mid) query(t[u].rc,mid+1,r,ql,qr,newnode);
}

bool bfs()
{
	memset(num,-1,sizeof(num));
	memcpy(cur,head,sizeof(cur));
	num[S]=0;
	q.push(S);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int i=head[u];i;i=nxt[i])
		{
			int v=to[i];
			if(c[i]&&num[v]==-1)
			{
				num[v]=num[u]+1;
				q.push(v);
			}
		}
	}
	return num[T]!=-1;
}

int dfs(int u,int minflow)
{
	if(!minflow||u==T) return minflow;
	int preflow=0,nowflow;
	for(register int i=cur[u];i;i=nxt[i])
	{
		cur[u]=i;
		int v=to[i];
		if(num[v]==num[u]+1&&(nowflow=dfs(v,min(minflow-preflow,c[i]))))
		{
			preflow+=nowflow;
			c[i]-=nowflow;
			c[i^1]+=nowflow;
			if(!(minflow-preflow)) break;
		}
	}
	return preflow;
}

int dinic()
{
	int maxflow=0;
	while(bfs())
		maxflow+=dfs(S,INF);
	return maxflow;
}

int main()
{
	n=read();
	S=1,T=1+n+1;
	for(register int i=1;i<=n;i++)
	{
		a[i].a=read(),a[i].b=read(),a[i].w=read(),a[i].l=read(),a[i].r=read(),a[i].p=read();
		b[++tot]=a[i].l,b[++tot]=a[i].r,b[++tot]=a[i].a;
		sum+=a[i].b+a[i].w;
		adde(S,1+i,a[i].b);
		adde(1+i,T,a[i].w);
	}
	sort(b+1,b+tot+1);
	int nn=unique(b+1,b+tot+1)-b-1;
	for(register int i=1;i<=n;i++)
	{
		a[i].a=lower_bound(b+1,b+nn+1,a[i].a)-b;
		a[i].l=lower_bound(b+1,b+nn+1,a[i].l)-b;
		a[i].r=lower_bound(b+1,b+nn+1,a[i].r)-b;
	}
//	build(root[0],1,nn);
	for(register int i=1;i<=n;i++)
	{
		update(root[i-1],root[i],1,nn,a[i].a,i);
		++node,adde(1+i,T+node,a[i].p);
		query(root[i-1],1,nn,a[i].l,a[i].r,T+node);
	}
	printf("%d
",sum-dinic());
	return 0;
}
/*
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
*/
/*
2
2 2 100 1 3 25
2 100 2 1 3 25
*/
原文地址:https://www.cnblogs.com/ez-lcw/p/14448673.html