对于x和y我们建立二分图,一个点将相应的xy相连,那么我们也就是要给边分配红还是蓝,加入给T分个红,如果横坐标为x的点位z个那么|2*T-z|<=d, 也就是(z-d)/2<=t<=(z+d)/2,因为红蓝独立,所以我们只需要跑一遍上下界最大流即可。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<string.h>
#include<queue>
#define maxn 200015
#define inf 100000000
using namespace std;
struct pi
{
int to;
int cost;
int rev;
int id;
}pp;
vector<pi >g[maxn];
queue<int>q;
int s,t;
int line[maxn],leve[maxn];
int min(int a,int b)
{
int p;
p=a;
if(b<a)
p=b;
return p;
}
void add(int a,int b,int cos,int id)
{
pp.to=b;
pp.cost=cos;
pp.id=id;
pp.rev=(int)g[b].size();
g[a].push_back(pp);
pp.to=a;
pp.cost=0;
pp.id=id;
pp.rev=(int)g[a].size()-1;
g[b].push_back(pp);
return ;
}
void insert(int a,int b,int l,int r){
add(s,b,l,-1);
add(a,b,r-l,-1);
add(a,t,l,-1);
}
void bfs(void)
{
q.push(s);
int p,f,i;
while(!q.empty())
{
p=q.front();
q.pop();
f=(int)g[p].size();
for(i=0;i<f;i++)
{
pi &e=g[p][i];
if(e.cost>0&&line[e.to]<0)
{
line[e.to]=line[p]+1;
q.push(e.to);
}
}
}
return ;
}
int dfs(int v,int f)
{
int p;
if(v==t)
return f;
for(int &i=leve[v];i<g[v].size();i++)
{
pi &e=g[v][i];
if(line[v]<line[e.to]&&e.cost>0)
{
p=dfs(e.to,min(f,e.cost));
if(p>0)
{
e.cost-=p;
g[e.to][e.rev].cost+=p;
return p;
}
}
}
return 0;
}
int dinic()
{
int f;
int flow=0;
while(1)
{
memset(line,-1,sizeof(line));
memset(leve,0,sizeof(leve));
line[s]=0;
bfs();
if(line[t]<0)
return flow;
f=dfs(s,inf);
if(f==0)
continue;
flow+=f;
while((f=dfs(s,inf))>0)
{
flow+=f;
}
}
}
int x[maxn],y[maxn];
struct in{
int x,y;
}pp1[maxn];
int l[maxn],r[maxn];
int ans[maxn];
set<int>xx,yy;
int up[maxn],dow[maxn];
int main()
{
int n,m;
int u=0;
int r1,b1;
cin>>n>>m;
cin>>r1>>b1;
if(r1<b1) {
u=1;
swap(r1,b1);
}
for(int i=1;i<=n;i++){
scanf("%d%d",&pp1[i].x,&pp1[i].y);
x[i]=pp1[i].x;
y[i]=pp1[i].y;
xx.insert(x[i]);
yy.insert(y[i]);
}
sort(x+1,x+1+n);
sort(y+1,y+1+n);
for(int i=1;i<=n;i++){
pp1[i].x=lower_bound(x+1,x+1+n,pp1[i].x)-x;
pp1[i].y=lower_bound(y+1,y+1+n,pp1[i].y)-y;
add(pp1[i].x,pp1[i].y+n,1,i);
l[pp1[i].x]++;
r[pp1[i].y]++;
}
s=0;
t=2*n+3;
for(int i=1;i<=n;i++){
up[i]=l[i];
dow[i]=r[i];
}
for(int i=0;i<m;i++){
int p,x1,d;
scanf("%d%d%d",&p,&x1,&d);
if(p==1){
if(xx.find(x1)==xx.end()) continue;
x1=lower_bound(x+1,x+1+n,x1)-x;
up[x1]=min(up[x1],d);
}
else{
if(yy.find(x1)==yy.end()) continue;
x1=lower_bound(y+1,y+1+n,x1)-y;
dow[x1]=min(dow[x1],d);
}
}
for(int i=1;i<=n;i++){
int u0,d0;
u0=(l[i]+up[i])/2;
d0=(l[i]-up[i])/2;
if(2*d0<l[i]-up[i]) d0++;
if(u0<d0){
printf("-1\n");
return 0;
}
else {
if(d0<0) d0=0;
insert(2*n+1,i,d0,u0);
}
u0=(r[i]+dow[i])/2;
d0=(r[i]-dow[i])/2;
if(2*d0<r[i]-dow[i]) d0++;
if(u0<d0){
printf("-1\n");
return 0;
}
else {
if(d0<0) d0=0;
insert(n+i,2*n+2,d0,u0);
}
}
dinic();
add(2*n+2,2*n+1,inf,-1);
dinic();
int flag=0;
for(pi v:g[s]){
if(v.cost>0) flag=1;
}
if(flag) printf("-1\n");
else {
int w=0;
for(pi v:g[2*n+1]){
if(v.to==2*n+2){
w=v.cost;
}
}
long long s=(long long)w*r1+(long long)(n-w)*b1;
cout<<s<<endl;
for(int i=1;i<=n;i++){
for(pi v:g[i]){
if(v.cost==0&&v.id!=-1){
ans[v.id]=1;
}
}
}
for(int i=1;i<=n;i++){
if(u==0){
if(ans[i]) printf("r");
else printf("b");
}
else{
if(ans[i]) printf("b");
else printf("r");
}
}
printf("\n");
}
}