CF704D Captain America 题解
考虑如果没有限制,那么我们肯定全为\(r\)或者全为\(b\),然后在有限制的情况下,花费小的越多越好,就是一个上下界有源汇最大流的板子题目了。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int inf=1e18;
const int maxn=1e5+10;
const int MX=4e5+10;
const int mxn=6e6+10;
int n,m,r,b,x[maxn],y[maxn],ge,li1[maxn],s,t,cnt1,cnt2,li2[maxn],lin1,lin2,lin3;
int cx[maxn],cy[maxn],lmx[maxn],lmy[maxn],lin,tot=1,head[MX],nxt[mxn],to[mxn];
int cap[mxn],xj,sj,sum,S,T,d[MX],ans,cnt[MX],vis[MX],cur[MX];
void add(int q,int w,int qw){
tot++;
nxt[tot]=head[q];
head[q]=tot;
to[tot]=w;
cap[tot]=qw;
tot++;
nxt[tot]=head[w];
head[w]=tot;
to[tot]=q;
return;
}
int spfa(){
for(int i=1;i<=ge;i++){
cnt[i]=inf;
vis[i]=0;
cur[i]=head[i];
}
queue<int>Q;
Q.push(S);
cnt[S]=0;
while(!Q.empty()){
int now=Q.front();
Q.pop();
if(vis[now]){
continue;
}
vis[now]=1;
for(int i=head[now];i;i=nxt[i]){
if(cnt[to[i]]>cnt[now]+1&&cap[i]){
cnt[to[i]]=cnt[now]+1;
Q.push(to[i]);
}
}
}
if(cnt[T]!=inf){
return 1;
}
return 0;
}
int dfs(int q,int w){
if(q==T){
return w;
}
int sum=0;
for(int i=cur[q];i;i=nxt[i]){
cur[q]=i;
if(cnt[to[i]]==cnt[q]+1&&cap[i]){
int flow=dfs(to[i],min(cap[i],w));
if(flow){
cap[i]-=flow;
cap[i^1]+=flow;
sum+=flow;
w-=flow;
if(!w){
return sum;
}
}
}
}
return sum;
}
int dinic(){
int ss=0;
while(spfa()){
ss+=dfs(S,inf);
}
return ss;
}
void init(){
cin>>n>>m>>r>>b;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i];
}
cnt1=0;
for(int i=1;i<=n;i++){
cnt1++;
li1[cnt1]=x[i];
}
sort(li1+1,li1+1+cnt1);
cnt1=unique(li1+1,li1+1+cnt1)-li1-1;
for(int i=1;i<=n;i++){
x[i]=lower_bound(li1+1,li1+1+cnt1,x[i])-li1;
cx[x[i]]++;
}
for(int i=1;i<=cnt1;i++){
lmx[i]=cx[i];
}
cnt2=0;
for(int i=1;i<=n;i++){
cnt2++;
li2[cnt2]=y[i];
}
sort(li2+1,li2+1+cnt2);
cnt2=unique(li2+1,li2+1+cnt2)-li2-1;
for(int i=1;i<=n;i++){
y[i]=lower_bound(li2+1,li2+1+cnt2,y[i])-li2;
cy[y[i]]++;
}
for(int i=1;i<=cnt2;i++){
lmy[i]=cy[i];
}
ge=cnt1+cnt2;
ge++;
s=ge;
ge++;
t=ge;
ge++;
S=ge;
ge++;
T=ge;
for(int i=1;i<=n;i++){
add(x[i],y[i]+cnt1,1);
}
for(int i=1;i<=m;i++){
cin>>lin1>>lin2>>lin3;
if(lin1==1){
lin=lower_bound(li1+1,li1+1+cnt1,lin2)-li1;
if(lin2!=li1[lin]){
continue;
}
lmx[lin]=min(lmx[lin],lin3);
}
else{
lin=lower_bound(li2+1,li2+1+cnt2,lin2)-li2;
if(lin2!=li2[lin]){
continue;
}
lmy[lin]=min(lmy[lin],lin3);
}
}
for(int i=1;i<=cnt1;i++){
xj=(cx[i]-lmx[i]+1)/2;
sj=(cx[i]+lmx[i])/2;
if(xj>sj){
cout<<-1;
exit(0);
}
else{
if(sj-xj)add(s,i,sj-xj);
d[s]-=xj;
d[i]+=xj;
}
}
for(int i=1;i<=cnt2;i++){
xj=(cy[i]-lmy[i]+1)/2;
sj=(cy[i]+lmy[i])/2;
if(xj>sj){
cout<<-1;
exit(0);
}
else{
if(sj-xj)add(i+cnt1,t,sj-xj);
d[i+cnt1]-=xj;
d[t]+=xj;
}
}
for(int i=1;i<=ge;i++){
if(d[i]<0){
add(i,T,-d[i]);
}
if(d[i]>0){
add(S,i,d[i]);
sum+=d[i];
}
}
add(t,s,inf);
return;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
init();
if(dinic()!=sum){
cout<<-1;
return 0;
}
S=s;
T=t;
ans=dinic();
cout<<1ll*ans*min(r,b)+1ll*(n-ans)*max(r,b)<<'\n';
for(int i=1;i<=n;i++){
if(cap[i*2]&&r<b){
cout<<"b";
}
else if(cap[i*2]==0&&b<r){
cout<<"b";
}
else{
cout<<"r";
}
}
return 0;
}
浙公网安备 33010602011771号