【CF704D】Captain America

跟着长郡军团做的一道题。

题面

https://www.luogu.org/problem/CF704D

题解

上下界网络流傻逼题。

注意判无解的第二种姿势:$l[i]>r[i]$

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#define LL long long
#define ri register int
#define N 250000
#define INF 1000000007
using namespace std;

int n,m,ccx=0,ccy=0,x[N],y[N];
int p[N],le[N],re[N];
int numx[N],numy[N];
map<int,int> otx,oty;

int idx(int x) {
  if (!otx.count(x)) otx[x]=++ccx;
  return otx[x];
}
int idy(int y) {
  if (!oty.count(y)) oty[y]=++ccy;
  return oty[y];
}

struct graph {
  vector<int> ed[N],w,to;
  int d[N],cur[N]; int S,T;
  void add_edge(int u,int v,int tw) {
    to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1);
    to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
  }
  bool bfs() {
    queue<int> q;
    memset(d,0x3f,sizeof(d));
    d[S]=0; q.push(S);
    while (!q.empty()) {
      int x=q.front(); q.pop();
      for (ri i=0;i<ed[x].size();i++) {
        int e=ed[x][i];
        if (d[x]+1<d[to[e]] && w[e]) {
          d[to[e]]=d[x]+1;
          q.push(to[e]);
        }
      }
    }
    return d[T]<INF;
  }
  int dfs(int x,int limit) {
    if (x==T || limit==0) return limit;
    int sum=0; 
    for (ri &i=cur[x];i<ed[x].size();i++) {
      int e=ed[x][i];
      if (w[e] && d[x]+1==d[to[e]]) {
        int f=dfs(to[e],min(limit,w[e]));
        if (!f) continue;
        sum+=f; limit-=f; 
        w[e]-=f; w[1^e]+=f;
        if (!limit) return sum;
      }
    }
    return sum;
  }
  int dinic() {
    int ret=0;
    while (bfs()) {
      memset(cur,0,sizeof(cur));
      ret+=dfs(S,INF);
    }
    return ret;
  }
} G;

int main() {
  int t,l,d; LL r,b;
  scanf("%d %d",&n,&m);
  scanf("%lld %lld",&r,&b);
  for (ri i=1;i<=n;i++) {
    scanf("%d %d",&x[i],&y[i]);
    x[i]=idx(x[i]);y[i]=idy(y[i]);
    numx[x[i]]++; numy[y[i]]++;
  }
  for (ri i=1;i<=ccx;i++) le[i]=0,re[i]=numx[i];
  for (ri i=1;i<=ccy;i++) le[ccx+i]=0,re[ccx+i]=numy[i];
  for (ri i=1;i<=m;i++) {
    scanf("%d %d %d",&t,&l,&d);
    if (t==1) {
      if (!otx.count(l)) continue;
      int nx=otx[l]; l=otx[l];
      if ((numx[l]+d)%2==0) {
        le[nx]=max(le[nx],(numx[l]-d)/2);
        re[nx]=min(re[nx],(numx[l]+d)/2);
      }
      else {
        le[nx]=max(le[nx],(numx[l]-d+1)/2);
        re[nx]=min(re[nx],(numx[l]+d-1)/2);
      }
    }
    else {
      if (!oty.count(l)) continue;
      int ny=oty[l]+ccx; l=oty[l];
      if ((numy[l]+d)%2==0) {
        le[ny]=max(le[ny],(numy[l]-d)/2);
        re[ny]=min(re[ny],(numy[l]+d)/2);
      }
      else {
        le[ny]=max(le[ny],(numy[l]-d+1)/2);
        re[ny]=min(re[ny],(numy[l]+d-1)/2);
      }
    }
  }
  int S=0,T=ccx+ccy+1;
  int SS=ccx+ccy+2,TT=ccx+ccy+3;
  for (ri i=1;i<=ccx;i++) {
    if (re[i]<le[i]) {
      printf("-1");
      return 0;
    }
    p[S]-=le[i],p[i]+=le[i];
    G.add_edge(S,i,re[i]-le[i]);
  }
  for (ri i=ccx+1;i<=ccx+ccy;i++) {
    if (re[i]<le[i]) {
      printf("-1");
      return 0;
    }
    p[T]+=le[i],p[i]-=le[i];
    G.add_edge(i,T,re[i]-le[i]);
  }
  for (ri i=1;i<=n;i++) G.add_edge(x[i],ccx+y[i],1);
  int ds=0;
  for (ri i=S;i<=T;i++) {
    if (p[i]>0) G.add_edge(SS,i,p[i]),ds+=p[i];
    else if (p[i]<0) G.add_edge(i,TT,-p[i]);
  }
  G.add_edge(T,S,INF);
  G.S=SS; G.T=TT;
  int tm=G.dinic();
  if (tm!=ds) { printf("-1"); return 0;}
  int flow1=G.w[G.w.size()-1];
  G.w[G.w.size()-2]=G.w[G.w.size()-1]=0;
  for (ri i=0,l=G.w.size();i<l;i++) {
    if (G.to[i]==SS || G.to[i]==TT || G.to[i^1]==SS || G.to[i^1]==TT) G.w[i]=0;
  }
  G.S=S; G.T=T;
  int flow=flow1+G.dinic();
  if (r<b) {
    LL ans=r*1LL*flow+(n-flow)*1LL*b;
    printf("%lld\n",ans);
    for (ri i=0,l=G.to.size();i<l;++i) {
      if (G.to[i]>ccx && G.to[i]<=ccx+ccy && G.to[i^1]>=1 && G.to[i^1]<=ccx) putchar(G.w[i]?'b':'r');
    }
  }
  else {
    LL ans=r*1LL*(n-flow)+b*1LL*flow;
    printf("%lld\n",ans);
    for (ri i=0,l=G.to.size();i<l;++i) {
      if (G.to[i]>ccx && G.to[i]<=ccx+ccy && G.to[i^1]>=1 && G.to[i^1]<=ccx) putchar(G.w[i]?'r':'b');
    }
  }
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/shxnb666/p/11275036.html