zoukankan      html  css  js  c++  java
  • CF704D Captain America

    Link
    不失一般性,不妨认为(rle b)
    假如我们先全部选(b),那么我们需要做的就是最大化将(b)变为(r)的个数。
    离散化,并对每一行和每一列新建一个点。
    对于第(i)行,假如原本这一行有(c_i)(b),最紧的限制为(d_i),那么我们需要将([lceilfrac{c_i-d_i}2 ceil,lfloorfrac{c_i+d_i}2 floor])(r)变成(b)
    对于第(i)列同理,记这一列原本的(b)的个数和最紧的限制为(C_i,D_i)
    那么我们可以将其转化为有源汇上下界最大流模型:
    (s ightarrow u_i:[lceilfrac{c_i-d_i}2 ceil,lfloorfrac{c_i+d_i}2 floor])(每一行的限制)
    (v_i ightarrow t:[lceilfrac{C_i-D_i}2 ceil,lfloorfrac{C_i+D_i}2 floor])(每一列的限制)
    (forall(x,y),u_x ightarrow v_y:[0,1])(将一个(b)变成一个(r)

    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #include<unordered_map>
    const int N=200007,M=N*5,inf=1e9;
    char ibuf[(1<<23)+1],*iS=ibuf;
    int x[N],y[N],tx[N],ty[N],cx[N],cy[N],lx[N],ly[N],id[N],d[N];
    int s,t,S,T,tot=1,head[N],ver[M],edge[M],next[M],cur[N],dep[N];std::queue<int>q;
    std::unordered_map<int,int>hx,hy;
    int read(){int x=0;while(isspace(*iS))++iS;while(isdigit(*iS))(x*=10)+=*iS++&15;return x;}
    void add(int u,int v,int w){ver[++tot]=v,next[tot]=head[u],edge[tot]=w,head[u]=tot,ver[++tot]=u,next[tot]=head[v],edge[tot]=0,head[v]=tot;}
    void Add(int u,int v,int l,int r){add(u,v,r-l),d[u]-=l,d[v]+=l;}
    int bfs(int s,int t)
    {
        memset(dep+1,-1,T<<2),memcpy(cur+1,head+1,T<<2),dep[s]=0,q.push(s);
        for(int i,u,v;!q.empty();) for(u=q.front(),q.pop(),i=head[u];i;i=next[i]) if(!~dep[v=ver[i]]&&edge[i]) dep[v]=dep[u]+1,q.push(v);
        return ~dep[t];
    }
    int dfs(int u,int t,int lim)
    {
        if(!lim||u==t) return lim;
        int v,flow=0;
        for(int&i=cur[u],f;i;i=next[i])
    	if(edge[i]&&dep[v=ver[i]]==dep[u]+1)
    	{
    	    flow+=(f=dfs(v,t,std::min(lim,edge[i]))),lim-=f,edge[i]-=f,edge[i^1]+=f;
    	    if(!lim) break;
    	}
        return flow;
    }
    int dinic(int s,int t){int r=0;while(bfs(s,t))r+=dfs(s,t,inf);return r;}
    int main()
    {
        fread(ibuf,1,1<<23,stdin);
        int n=read(),m=read(),r=read(),b=read(),mx,my,f=0,sum=0,ans=0;
        if(r>b) std::swap(r,b),f=1;
        for(int i=1;i<=n;++i) x[i]=read(),y[i]=read();
        memcpy(tx+1,x+1,n<<2),memcpy(ty+1,y+1,n<<2);
        std::sort(tx+1,tx+n+1),std::sort(ty+1,ty+n+1);
        mx=std::unique(tx+1,tx+n+1)-tx-1,my=std::unique(ty+1,ty+n+1)-ty-1;
        s=mx+my+1,t=s+1,S=t+1,T=S+1,add(t,s,inf);
        for(int i=1;i<=mx;++i) hx[tx[i]]=i;
        for(int i=1;i<=my;++i) hy[ty[i]]=i;
        for(int i=1;i<=n;++i) ++cx[x[i]=hx[x[i]]],++cy[y[i]=hy[y[i]]];
        for(int i=1;i<=n;++i) add(x[i],y[i]+mx,1),id[i]=tot^1;
        memcpy(lx+1,cx+1,mx<<2),memcpy(ly+1,cy+1,my<<2);
        for(int i=1,o,l,d;i<=m;++i)
        {
    	o=read(),l=read(),d=read();
    	if(o&1) {if(hx.count(l)) l=hx[l],lx[l]=std::min(lx[l],d);}
    	else {if(hy.count(l)) l=hy[l],ly[l]=std::min(ly[l],d);}
        }
        for(int i=1;i<=mx;++i) if(cx[i]&1&&!lx[i]) return puts("-1"),0; else Add(s,i,(cx[i]-lx[i]+1)/2,(cx[i]+lx[i])/2);
        for(int i=1;i<=my;++i) if(cy[i]&1&&!ly[i]) return puts("-1"),0; else Add(i+mx,t,(cy[i]-ly[i]+1)/2,(cy[i]+ly[i])/2);
        for(int i=1;i<=t;++i) if(d[i]>0) add(S,i,d[i]),sum+=d[i]; else if(d[i]<0) add(i,T,-d[i]);
        if((ans=dinic(S,T))^sum) return puts("-1"),0;
        ans=dinic(s,t),printf("%lld
    ",1ll*ans*r+1ll*(n-ans)*b);
        for(int i=1;i<=n;++i) putchar(edge[id[i]]^f? 'b':'r');
    }
    
  • 相关阅读:
    [转]OnKeyDown Numeric Validator CLIENT SIDE
    [转]ng-grid
    死锁
    MySQL中间层 Atlas
    构建高性能web之路------mysql读写分离实战
    springboot读写分离--temp
    MySQL数据库的同步配置+MySql读写分离
    JMX学习笔记(二)-Notification
    kafka之四:Kafka集群搭建
    Synchronized之四:Synchronized的可重入性
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12368882.html
Copyright © 2011-2022 走看看