题意:平面上有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 ;

}

Codeforces 704D Captain America的更多相关文章

  1. CF#366 704D Captain America 上下界网络流

    CF上的题,就不放链接了,打开太慢,直接上题面吧: 平面上有n个点, 第 i 个点的坐标为 ($X_i ,Y_i$), 你需要把每个点染成红色或者蓝色, 染成红色的花费为 r , 染成蓝色的花费为 b ...

  2. CF 704 D. Captain America

    CF 704 D. Captain America 题目链接 题目大意:给出\(n\)个点的坐标,你要将每个点染成红色或者蓝色.染一个红色要付出\(r\)的代价,染一个蓝色要付出\(b\)的代价.有\ ...

  3. 【CF704D】Captain America(上下界网络流)

    [CF704D]Captain America(上下界网络流) 题面 CF 洛谷 题解 如果没有限制,似乎就不用做了...因为我们只需要贪心的选择代价较小的颜色就行了. 那么我们不妨假设染红色的代价较 ...

  4. CF704D Captain America

    http://codeforces.com/problemset/problem/704/D 题解 对于两种颜色的染色,我们可以把它看做选择问题. 比如说红色的代价小,所以我们尽可能多的染红色. 然后 ...

  5. Codeforces 474C Captain Marmot 给定4个点和各自旋转中心 问旋转成正方形的次数

    题目链接:点击打开链接 题意: 给定T表示case数 以下4行是一个case 每行2个点,u v 每次u能够绕着v逆时针转90° 问最少操作多少次使得4个u构成一个正方形. 思路: 枚举判可行 #in ...

  6. CodeForces 474C Captain Marmot (数学,旋转,暴力)

    题意:给定 4n * 2 个坐标,分成 n组,让你判断,点绕点的最少次数使得四个点是一个正方形的顶点. 析:那么就一个一个的判断,n 很小,不会超时,四个点分别从不转然后转一次,转两次...转四次,就 ...

  7. codeforces704D Captain America【上下界最大流】

    分别给行和列hash建两排点,对(x,y)坐标连x行y列的点 设红色价格低,那么就要尽量多选红色 设一个点出度为s,要求最小的最大差值为d,又,假设有流量表示选红没流量表示选蓝,那么要求就变成了这个点 ...

  8. CF704D Captain America(上下界网络流)

    传送门 题意: 二维平面给出\(n\)个点,现在可以给每个点进行染色,染红色的代价为\(r\),染蓝色的代价为\(b\). 之后会有\(m\)个限制,形式如:\(t_i\ l_i\ d_i\),当\( ...

  9. CF704D Captain America 上下界网络流

    传送门 现在相当于说每一个条件都有一个染成红色的盾牌的数量限制\([l,r]\),需要满足所有限制且染成红色的盾牌数量最小/最大. 注意到一个盾牌染成红色对于一行和一列都会产生影响.如果选中一个物品对 ...

随机推荐

  1. 【转】spin_lock & mutex_lock的区别? .

    原文网址:http://blog.csdn.net/wilsonboliu/article/details/19190861 本文由该问题引入到内核锁的讨论,归纳如下   为什么需要内核锁? 多核处理 ...

  2. 多线程同步、异步(BeginInvoke)

    一.线程的基础知识 1 System.Threading.Thread类 System.Threading.Thread是用于控制线程的基础类,通过Thread可以控制当前应用程序域中线程的创建.挂起 ...

  3. Number of Islands——LeetCode

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  4. CSU 1111 有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园。A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕。C 太太因为正身怀六甲无法加入她们的行动,所以就打算出90元钱

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82974#problem/D 解题思路:本题的意思就是三位均出90,然后AB按做 ...

  5. Wad Manager的下载和运行

    关于WAD版的软件 WAD版的软件分为两种: 独立安装版:程序完全安装在Wii的内置存储空间上,可以在Wii的主界面直接启动软件. Forwarder版:程序安装在Wii的内置存储空间上,同时在SD卡 ...

  6. banana pro 板子

    http://www.lemaker.org/cn/article-23-1.html

  7. Robot Framework安装配置 windows

    1.install python https://www.python.org/downloads/release/python-279/ choose "Files" -> ...

  8. M - Jamie's Contact Groups - poj 2289(二分图多重匹配)

    题意:某个人通讯录有很多人,现在他想把这个人分组,给的数据是可以把这个人分在那些组里面,现在他想知道分组后,人最多的那个组至少有多少人. 分析:因为没有给组限制有多少人,可以使用二分求出来最小的那个, ...

  9. K - Treasure Exploration - POJ 2594(最小路径覆盖+闭包传递)

    题意:给一个有向无环图,求出来最小路径覆盖,注意一个点可能会被多条路径重复 分析:因为有可能多条路径走一个点,可又能会造成匹配的不完全,所以先进行一次闭包传递(floyd),然后再用二分匹配的方法求出 ...

  10. Heritrix的安装与配置 (最新版 已测试通过)

    本教程,结合本人亲身实践,不仅适合于最新版本Heritrix 1.14.4,更适合其他任何版本.Heritrix具体下载地址如下:      http://sourceforge.net/projec ...