Codeforces 704D Captain America
题意:平面上有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的更多相关文章
- CF#366 704D Captain America 上下界网络流
CF上的题,就不放链接了,打开太慢,直接上题面吧: 平面上有n个点, 第 i 个点的坐标为 ($X_i ,Y_i$), 你需要把每个点染成红色或者蓝色, 染成红色的花费为 r , 染成蓝色的花费为 b ...
- CF 704 D. Captain America
CF 704 D. Captain America 题目链接 题目大意:给出\(n\)个点的坐标,你要将每个点染成红色或者蓝色.染一个红色要付出\(r\)的代价,染一个蓝色要付出\(b\)的代价.有\ ...
- 【CF704D】Captain America(上下界网络流)
[CF704D]Captain America(上下界网络流) 题面 CF 洛谷 题解 如果没有限制,似乎就不用做了...因为我们只需要贪心的选择代价较小的颜色就行了. 那么我们不妨假设染红色的代价较 ...
- CF704D Captain America
http://codeforces.com/problemset/problem/704/D 题解 对于两种颜色的染色,我们可以把它看做选择问题. 比如说红色的代价小,所以我们尽可能多的染红色. 然后 ...
- Codeforces 474C Captain Marmot 给定4个点和各自旋转中心 问旋转成正方形的次数
题目链接:点击打开链接 题意: 给定T表示case数 以下4行是一个case 每行2个点,u v 每次u能够绕着v逆时针转90° 问最少操作多少次使得4个u构成一个正方形. 思路: 枚举判可行 #in ...
- CodeForces 474C Captain Marmot (数学,旋转,暴力)
题意:给定 4n * 2 个坐标,分成 n组,让你判断,点绕点的最少次数使得四个点是一个正方形的顶点. 析:那么就一个一个的判断,n 很小,不会超时,四个点分别从不转然后转一次,转两次...转四次,就 ...
- codeforces704D Captain America【上下界最大流】
分别给行和列hash建两排点,对(x,y)坐标连x行y列的点 设红色价格低,那么就要尽量多选红色 设一个点出度为s,要求最小的最大差值为d,又,假设有流量表示选红没流量表示选蓝,那么要求就变成了这个点 ...
- CF704D Captain America(上下界网络流)
传送门 题意: 二维平面给出\(n\)个点,现在可以给每个点进行染色,染红色的代价为\(r\),染蓝色的代价为\(b\). 之后会有\(m\)个限制,形式如:\(t_i\ l_i\ d_i\),当\( ...
- CF704D Captain America 上下界网络流
传送门 现在相当于说每一个条件都有一个染成红色的盾牌的数量限制\([l,r]\),需要满足所有限制且染成红色的盾牌数量最小/最大. 注意到一个盾牌染成红色对于一行和一列都会产生影响.如果选中一个物品对 ...
随机推荐
- HiveServer连接优化
引言 数据平台目前通过Hive SQL的方式提供数据分析服务,系统使用多台HiveServer(JDBCServer)接收客户端连接请求,实际使用场景中频频出现HiveServer内存消耗过多导致 ...
- openStack Use Orchestration module(heat) create and manage cloud resources
- Selenium索引
Common Selenium各种工具比较 Selenium firefox 版本问题 Selenium IDE Selenium IDE整理 WebDriver Java 版本 Selenium开始 ...
- Android testing tools
引言 发现一篇关于android 测试的培训,英文的,很全面. Android Testing Training: http://www.vogella.com/training/android/an ...
- 同时安装Xcode6和Xcode7导致出现N多UUID 模拟器解决办法
[摘要:1.完整退出Xcode 和 摹拟器 2.末端中输进以下两居指令 $ sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService$ ...
- hdu 2844
本题的特殊性是价值与重量相等 将第i种物品分成若干件物品,其中每件物品有一个系数, 这件物品的费用和价值均是原来的费用和价值乘以这个系数. 使这些系数分别为1,2,4,…,2^(k-1),n[i]-2 ...
- IOS开发之Post 方式获取服务器数据
//1.创建post方式的 参数字符串url +(NSString *)createPostURL:(NSMutableDictionary *)params { NSString *postStri ...
- Project Euler problem 61
题意很明了. 然后我大概的做法就是暴搜了 先把每个几边形数中四位数的处理出来. 然后我就DFS回溯着找就行了. 比较简单吧. #include <cstdio> #include < ...
- Android-语言设置流程分析
Android手机语言切换行为,是通过设置-语言和输入法-语言来改变手机的语言,其实这个功能很少被用户使用. 以Android5.1工程源码为基础,从设置app入手来分析和学习语言切换的过程: ...
- jquery中prop()方法和attr()方法的区别(转)
jquery1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了pro ...