其他分享
首页 > 其他分享> > BZOJ3218. a + b Problem

BZOJ3218. a + b Problem

作者:互联网

【题意】

 

 【分析】

考虑到这种节点较多,而且连的边有一定性质的,特别是类似区间上的问题,我们要用线段树优化建图取做网络流

【代码】

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fi first
#define se second
#define lson now<<1
#define rson now<<1|1
typedef long long ll;
int S,T,n,m;
const int maxn=200000+5;
const int maxm=720000+5;
const ll inf=1e17;
int head[maxn],tot=1;
struct edge
{
    int to,nxt;
    ll v;
}e[maxm<<1];
void add(int x,int y,ll z)
{
    e[++tot].to=y; e[tot].nxt=head[x]; e[tot].v=z; head[x]=tot;
    e[++tot].to=x; e[tot].nxt=head[y]; e[tot].v=0; head[y]=tot;
}
int dep[maxn];
bool bfs()
{
    memset(dep,-1,sizeof(dep));
    queue <int> q;
    dep[S]=0;
    q.push(S);
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        for(int i=head[u];i;i=e[i].nxt)
        {
            int to=e[i].to;
            if(dep[to]!=-1 || !e[i].v) continue;
            q.push(to);
            dep[to]=dep[u]+1;
        }
    }
    return (dep[T]!=-1);
}
ll dfs(int u,ll flow)
{
    if(u==T) return flow;
    ll res=0;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(dep[to]!=dep[u]+1 || e[i].v<=0) continue;
        ll tmp=dfs(to,min(e[i].v,flow));
        flow-=tmp; res+=tmp;
        e[i].v-=tmp; e[i^1].v+=tmp;
        if(!flow) break;
    }
    if(!res) dep[u]=-1;
    return res;
}
ll dinic()
{
    ll ans=0;
    while(bfs())
    {
        ans+=dfs(S,inf);
    }
    return ans;
}
int cnt,root[5005];
struct chairman_segtree
{
    int l,r;
}tr[maxn];
void update(int &now,int pre,int l,int r,int val,int id)
{
    now=++cnt;
    tr[now]=tr[pre];
    add(id,now,inf);
    if(l==r)
    {
        if(pre) add(pre,now,inf);
        return;
    }
    int mid=(l+r)>>1;
    if(val<=mid)
    {
        update(tr[now].l,tr[pre].l,l,mid,val,id);
        if(pre) add(pre,now,inf);
    }
    else
    {
        update(tr[now].r,tr[pre].r,mid+1,r,val,id);
        if(pre) add(pre,now,inf);
    }
}
void check(int now,int l,int r,int L,int R,int id)
{
    if(!now) return;
    int mid=(l+r)>>1;
    if(l>=L && r<=R)
    {
        add(now,id,inf);
        return;
    }
    if(l<=mid) check(tr[now].l,l,mid,L,R,id);
    if(mid<r) check(tr[now].r,mid+1,r,L,R,id);
}
int main()
{

    scanf("%d",&n);
    S=0; T=maxn-5; cnt=n<<1;
    int a,l,r; ll w,b,p,sum=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%lld%lld%d%d%lld",&a,&b,&w,&l,&r,&p);
        sum+=(w+b);
        add(S,i,w); add(i+n,i,p); add(i,T,b);
        update(root[i],root[i-1],0,1e9,a,i);
        check(root[i-1],0,1e9,l,r,i+n);
    }
    ll minus=dinic();
    printf("%lld",sum-minus);
    return 0;
}

 

标签:head,return,dep,ll,int,BZOJ3218,Problem,define
来源: https://www.cnblogs.com/andylnx/p/14845390.html