题意:平面上有n个点,每个点必须涂成红色和蓝色中的一种,花费各为r和b(对所有的点花费都一样).m条限制,每条限制形如”y=b这条直线上两种颜色的点的数目之差的绝对值不能超过c”或” x=b这条直线上两种颜色的点的数目之差的绝对值不能超过c”,点数和限制数10^5,坐标范围10^9.

首先看到坐标范围很大先离散化,然后变成100000*100000的网格图每行每列的限制.那么转化成二分图,原先的每个点转换成边.因为每一行每一列的总点数是已知的,”两种颜色的点的数目之差”就可以转化成红色点和蓝色点的数目范围.接下来不妨把所有点都涂成红色,然后如果蓝色的点比红色的点花费小我们就尽量多涂蓝点,否则尽量少涂蓝点.为了统一问题的形式,在蓝色的点花费小于红色的时候我们就先全涂上蓝色,然后尽量少涂红点.不妨认为现在红色点花费较少,先涂上红点再尽量少涂蓝点.

那么就成了有上下界的网络流问题.对第i行我们建一个点Li,对第j列我们建一个点Ri,从源点向每个Li连一条流量上下界为这一行的蓝色点数目范围的边(在求解蓝点数目范围的时候要考虑到蓝点的数目还应当大于等于0小于等于这一行/列的点数),对每个Ri向汇点连一条流量上下界为这一列的蓝色点数目范围的边,对于坐标为第i行第j列的点,我们从Li向Rj连一条下界为0上界为1的边.跑有上下界的最小流即可.

注意一开始求的蓝点的数目范围可能是空集,这时候直接输出-1,不要再dinic跑可行流了.不知道别人的代码怎么样,反正我的代码很矬,即使有下界>上界的边也能跑出个可行流…

代码稍微长点.

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

typedef long long ll;

const int maxn=,maxm=;

struct edge{

  int to,next,w,num;

}lst[maxm];int len=,first[maxn],_first[maxn];

void addedge(int a,int b,int w,int num=){

  lst[len].num=num;

  lst[len].to=b;lst[len].next=first[a];lst[len].w=w;first[a]=len++;

  lst[len].num=num;

  lst[len].to=a;lst[len].next=first[b];lst[len].w=;first[b]=len++;

}

int q[maxn],vis[maxn],dis[maxn],s,t,head,tail,T;

bool bfs(){

  head=tail=;vis[s]=++T;dis[s]=;q[tail++]=s;

  while(head!=tail){

    int x=q[head++];

    for(int pt=first[x];pt!=-;pt=lst[pt].next){

      if(lst[pt].w&&vis[lst[pt].to]!=T){

        vis[lst[pt].to]=T;dis[lst[pt].to]=dis[x]+;q[tail++]=lst[pt].to;

      }

    }

  }

  if(vis[t]==T)memcpy(_first,first,sizeof(first));

  return vis[t]==T;

}

int dfs(int x,int lim){

  if(x==t)return lim;

  int flow=,a;

  for(int pt=_first[x];pt!=-;pt=lst[pt].next){

    _first[x]=pt;

    if(lst[pt].w&&dis[lst[pt].to]==dis[x]+&&(a=dfs(lst[pt].to,min(lst[pt].w,lim-flow)))){

      lst[pt].w-=a;lst[pt^].w+=a;flow+=a;

      if(flow==lim)return flow;

    }

  }

  return flow;

}

int dinic(){

  int ans=,x;

  while(bfs())

    while(x=dfs(s,0x7f7f7f7f))ans+=x;

  return ans;

}

void del(int x){

  for(int pt=first[x];pt!=-;pt=lst[pt].next)lst[pt].w=lst[pt^].w=;

}

int totflow[maxn];

int bound_flow(){//s-t minimum flow with lowerbound and upperbound

  int ss=t+,tt=t+;

  int sum=;

  for(int i=s;i<=t;++i){

    if(totflow[i]<){

      addedge(i,tt,-totflow[i]);

    }else{

      sum+=totflow[i];

      addedge(ss,i,totflow[i]);

    }

  }

  addedge(t,s,0x7f7f7f7f);

  int tmps=s,tmpt=t;

  s=ss;t=tt;

  if(dinic()!=sum){

    printf("-1\n");return -;

  }else{//return 0;

    int ans0=lst[len-].w;

    lst[len-].w=lst[len-].w=;

    del(ss);del(tt);

    s=tmpt;t=tmps;//printf("!");

    return ans0-dinic();

  }

}

void Add(int a,int b,int lo,int hi,int num=){//printf("%d %d %d %d\n",a,b,lo,hi);

  totflow[a]-=lo;totflow[b]+=lo;

  addedge(a,b,hi-lo,num);

}

int n,m,r,b;

int x[maxn],y[maxn],typ[maxn],pos[maxn],delta[maxn];

int lbx[maxn],ubx[maxn],lby[maxn],uby[maxn];

int val[maxn],seq[maxn];

bool cmp(const int &a,const int &b){

  return val[a]<val[b];

}

int discrete(int x[],int _typ){

  int tot=,old=-,cnt=;

  for(int i=;i<=n;++i){

    val[++tot]=x[i];

  }

  for(int i=;i<=m;++i){

    if(typ[i]==_typ)val[++tot]=pos[i];

  }

  for(int i=;i<=tot;++i)seq[i]=i;

  sort(seq+,seq+tot+,cmp);

  for(int i=;i<=tot;++i){

    if(val[seq[i]]!=old){

      old=val[seq[i]];++cnt;

    }

    val[seq[i]]=cnt;

  }

  tot=;

  for(int i=;i<=n;++i){

    x[i]=val[++tot];

  }

  for(int i=;i<=m;++i){

    if(typ[i]==_typ)pos[i]=val[++tot];

  }

  return cnt;

}

int cntx[maxn],cnty[maxn];

int res[maxn];

int main(){

  memset(first,-,sizeof(first));

  scanf("%d%d",&n,&m);

  scanf("%d%d",&r,&b);

  bool reversed = false;

  if(r>b)swap(r,b),reversed=true;

  for(int i=;i<=n;++i){

    scanf("%d%d",&x[i],&y[i]);

  }

  for(int i=;i<=m;++i){

    scanf("%d%d%d",typ+i,pos+i,delta+i);

  }

  int totx=discrete(x,),toty=discrete(y,);

  //for(int i=1;i<=n;++i)printf("%d %d\n",x[i],y[i]);

  //for(int i=1;i<=m;++i)printf("%d %d %d\n",typ[i],pos[i],delta[i]);

  for(int i=;i<=n;++i)cntx[x[i]]++,cnty[y[i]]++;

  ll ans=r*1LL*n;

  for(int i=;i<=totx;++i){

    lbx[i]=;ubx[i]=cntx[i];

  }

  for(int i=;i<=toty;++i){

    lby[i]=;uby[i]=cnty[i];

  }

  for(int i=;i<=m;++i){

    if(typ[i]==){

      lbx[pos[i]]=max(lbx[pos[i]],(cntx[pos[i]]-delta[i]+)/);ubx[pos[i]]=min(ubx[pos[i]],(cntx[pos[i]]+delta[i])/);

    }else{

      lby[pos[i]]=max(lby[pos[i]],(cnty[pos[i]]-delta[i]+)/);uby[pos[i]]=min(uby[pos[i]],(cnty[pos[i]]+delta[i])/);

    }

  }

  s=;t=totx+toty+;

  bool no_solution=false;

  for(int i=;i<=totx;++i){

    Add(s,i,lbx[i],ubx[i]);

    if(lbx[i]>ubx[i])no_solution=true;//神坑

  }//printf("!");

  for(int i=;i<=toty;++i){

    Add(totx+i,t,lby[i],uby[i]);

    if(lby[i]>uby[i])no_solution=true;//神坑

  }//printf("!");

  for(int i=;i<=n;++i){//printf("!");

    Add(x[i],totx+y[i],,,i);

  }//printf("!");

  if(no_solution){

    printf("-1\n");return ;

  }

  int flow=bound_flow();

  if(flow!=-){

    printf("%lld\n",ans+flow*1LL*(b-r));

    for(int i=;i<=totx;++i){

      for(int pt=first[i];pt!=-;pt=lst[pt].next){

        if(lst[pt].num!=&&lst[pt].w==){

          res[lst[pt].num]=;

        }

      }

    }//printf("?");

    if(reversed){

      for(int i=;i<=n;++i)printf("%c",res[i]?'r':'b');

    }else{

      for(int i=;i<=n;++i)printf("%c",res[i]?'b':'r');

    }printf("\n");

  }

  return ;

}

最新文章

  1. 从下拉菜单拖拽一个元素 出来,插入到页面中的app 列表中
  2. 安卓图表引擎AChartEngine(一) - 简介
  3. 基于SWFUpload的angular上传组件
  4. ASP.NET简单登录注册实例
  5. 有关PHP的字符串知识
  6. Incorrect integer value: &#39;&#39; for column &#39;id&#39; at row 1
  7. TWinControl与TControl的覆盖函数(TWinControl对TControl的10个消息覆盖函数,17个覆盖函数,私有虚函数仍可多态)
  8. PHP之SQL防注入代码(360提供)
  9. Poj3680 Intervals
  10. oracle 创建表空间、创建用户管理该表空间
  11. [AngularJS] Services, Factories, and Providers -- value &amp; Providers
  12. css基础回顾-定位:position
  13. BubbleSort - 实用委托
  14. ZOJ 3745 Salary Increasing
  15. 浅谈 Java Xml 底层解析方式
  16. 理解Vue中的Render渲染函数
  17. CentOS7.x机器安装Azure CLI2.0
  18. linux centos6.5安装KVM
  19. python 写代码笔记 2017.6.15
  20. 学习animate.css包含了一组炫酷、有趣、跨浏览器的动画

热门文章

  1. 《Linear Algebra and Its Application》-chaper1-行化简法解决线性方程组
  2. Flask+Mysql搭建网站之网页设计
  3. 在Eclipse中新建Maven项目
  4. linux内核--自旋锁的理解
  5. win7安装ruby on rails
  6. tcp/ip状态图
  7. object- c 字符串操作
  8. Android ViewFlow的一个例子
  9. Android消息机制(2)
  10. RDF Database和NoSql DB