• 【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
    */
    
  • 相关阅读:
    解题:HNOI 2008 玩具装箱
    2016级算法第一次上机助教版解题报告
    求解斐波那契数列复杂度分析
    数据库复习之规范化理论应用(第八次上机内容)
    数据库复习之规范化理论
    题目1042:Coincidence(最长公共子序列)
    题目1020:最小长方形(简单)
    题目1016:火星A+B(字符串拆分)
    题目1014:排名(结构体排序)
    题目1021:统计字符(hash简单应用)
  • 原文地址:https://www.cnblogs.com/ez-lcw/p/14448673.html
Copyright © 2020-2023  润新知