zoukankan      html  css  js  c++  java
  • BZOJ3218 a+b Problem

    这样复杂的限制条件显然是一道网络流题,考虑建图完成最小割。

    难点在于不同的点黑白相互制约,假设没有这一限制,建图很显然。

    设源点$S$,汇点$T$,对于第$i$个点:

    ·从$S$出发向$i$连容量为$b_i$的边。

    ·从$i$出发向$T$连容量为$w_i$的边。

    如何加入$p_i$的限制呢?

    对于一个点$i$,和所有满足$1leq j<i,l_ileq a_jleq r_i$的$j$。

    当$p_i$要被割掉,当且仅当存在$w_j$没有被割掉且$b_i$没被割掉。

    因此对于$i$要确保有一条$b_ispace ightarrowspace p_ispace ightarrowspace w_j$的边。

    所以对于每个点$i$设值一个新点$i'$,从$i$向$i'$连一条容量为$p_i$的边。

    对于$i$的每一个$j$,从$i'$向$j$链接一条容量为正无穷的边。

    由于$n$达到了$5000$,所以我们要考虑使用主席树优化建图。

    其实很简单,就是把主席上的每个节点连向左右儿子,对于值域为$[a_i,a_i]$叶子节点连向$a_i$对应节点的$i$。

    每次插入数之前,将$i'$连向主席上的$[l_i,r_i]$的区间,这样点数边数均在$nspace log(n)$级别。

    然而为什么我的代码跑的这么慢啊。

    哪位大佬来教教我网络流怎么写啊啊啊啊啊。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define M 600020
    #define N 10010
    #define INF 2000000020
    #define mid (l+r>>1)
    using namespace std;
    int read(){
        int nm=0,fh=1;char cw=getchar();
        for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
        for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
        return nm*fh;
    }
    int n,m,fs[M],nt[M],to[M],r[M],cnt,ans,vis[M];
    int A[N],B[N],W[N],ls[N],rs[N],P[N],S,T,tot;
    int L[M],R[M],rt[M],tmp,cur[M],q[M],hd,tl;
    struct Q{int kd,ps,nw;}sq[M];
    bool cmp(Q i,Q j){return i.nw==j.nw?i.kd<j.kd:i.nw<j.nw;}
    inline void addedge(int x,int y,int rem){
        nt[tmp]=fs[x],fs[x]=tmp,to[tmp]=y,r[tmp++]=rem;
        nt[tmp]=fs[y],fs[y]=tmp,to[tmp]=x,r[tmp++]=0;
    }
    void update(int x,int l,int r,int LS,int RS,int node){
        if(RS<l||r<LS||x==0) return;
        if(LS<=l&&r<=RS) return addedge(node,x,INF);
        update(L[x],l,mid,LS,RS,node);
        update(R[x],mid+1,r,LS,RS,node);
    }
    void ins(int &x,int pre,int l,int r,int pos,int node){
        x=++cnt,L[x]=L[pre],R[x]=R[pre];
        if(l==r) return addedge(x,node,INF);
        //注意这里是因为在离散化时保证了每个ai,li,ri互不相同
    	//否则可能会出现ai相同的情况,需要特判 
    	//if(l==r&&pre>0) addedge(x,pre,INF) 
        if(pos<=mid) ins(L[x],L[pre],l,mid,pos,node);
        else ins(R[x],R[pre],mid+1,r,pos,node);
        if(L[x]) addedge(x,L[x],INF);
        if(R[x]) addedge(x,R[x],INF);
    }
    bool BFS(){
        for(int i=1;i<=cnt;i++) vis[i]=-1;
        hd=tl=0,vis[S]=1,q[tl++]=S,cur[S]=fs[S];
        while(hd<tl){
            int x=q[hd++];
            for(int i=fs[x];i!=-1;i=nt[i]){
                if(vis[to[i]]>0||r[i]==0) continue;
                vis[to[i]]=vis[x]+1,q[tl++]=to[i];
                cur[to[i]]=fs[to[i]];
            }
        }
        return vis[T]>0;
    }
    int DFS(int x,int mxf){
        if(x==T||mxf==0) return mxf;
        int temp=0;
        for(int &i=cur[x];i!=-1;i=nt[i]){
            if(r[i]==0||vis[to[i]]!=vis[x]+1) continue;
            int rc=DFS(to[i],min(r[i],mxf-temp));
            temp+=rc,r[i]-=rc,r[i^1]+=rc;
            if(temp==mxf) break;
        }
        if(temp==0) vis[x]=-1;
        return temp;
    }
    inline void DINIC(){for(;BFS();ans-=DFS(S,INF));}
    int main(){
        n=read(),S=(n<<1),S++,T=S,T++,cnt=T;
        memset(fs,-1,sizeof(fs));
        for(int i=1;i<=n;i++){
            A[i]=read(),B[i]=read(),W[i]=read();
            ls[i]=read(),rs[i]=read(),P[i]=read();
            ans+=B[i]+W[i],addedge(i,i+n,P[i]);
    		addedge(S,i,B[i]),addedge(i,T,W[i]);
            tot++,sq[tot].kd=0,sq[tot].ps=i,sq[tot].nw=ls[i];
            tot++,sq[tot].kd=1,sq[tot].ps=i,sq[tot].nw=A[i];
            tot++,sq[tot].kd=2,sq[tot].ps=i,sq[tot].nw=rs[i];
        }
        sort(sq+1,sq+tot+1,cmp),tot=0;
        for(int i=1;i<=n*3;i++,tot++){
        	if(sq[i].kd==0) ls[sq[i].ps]=tot;
        	if(sq[i].kd==1) A[sq[i].ps]=tot;
        	if(sq[i].kd==2) rs[sq[i].ps]=tot;
    	}
        for(int i=1;i<=n;i++){
    		update(rt[i-1],0,tot,ls[i],rs[i],i+n);
            ins(rt[i],rt[i-1],0,tot,A[i],i);
        }
        DINIC(),printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    unity与android交互总结
    Unity3d 下websocket的使用
    Unity的Shader如何控制投影颜色
    _LightColor0将会是主要的directional light的颜色。
    Unity shader saturate
    今天写shader流光效果,shader代码少了个括号,unity shader compiler卡死且不提示原因
    欧几里得空间
    Unity ios、android、pc一键打包(一)
    [AR]高通Vuforia Getting Started
    unity3d 为什么要烘焙?烘焙作用是为了什么?
  • 原文地址:https://www.cnblogs.com/OYJason/p/9489275.html
Copyright © 2011-2022 走看看