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');
}