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]\),需要满足所有限制且染成红色的盾牌数量最小/最大. 注意到一个盾牌染成红色对于一行和一列都会产生影响.如果选中一个物品对 ...
随机推荐
- DataGridView DataGridViewCheckBoxColumn编辑时实时触发事件
正常响应CellValueChanged()事件时,当改变checkbox状态时,只有当焦点离开该单元格时才能触发CellValueChanged()事件, 如果要改变checkbox值时实时触发Ce ...
- pdf打印乱码问题
问题: 使用Adobe Reader将一份pdf文件通过我的虚拟打印机输出后(输出的是中间文件,等同于EMF文件),查看的时候发现有时候是乱码.最简单的必现步骤: 1.使用Adobe Reader打开 ...
- Fastjson Feathure
转载于:http://code.alibabatech.com/wiki/display/FastJSON/Serial+Features Fastjson序列化时,可以指定序列化的特性,以满足不同的 ...
- Android开发之扫描附近wifi热点并列表显示
近期项目中用到了wifi模块.今天做一个简单的总结. 參考:http://www.2cto.com/kf/201310/253617.html 1.如何获取wifi对象并进行操作 要操作WIFI设备, ...
- .NET注册页面代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- js中的隐式转换
js中的不同的数据类型之间的比较转换规则如下: 1. 对象和布尔值比较 对象和布尔值进行比较时,对象先转换为字符串,然后再转换为数字,布尔值直接转换为数字 [] == true; //false [] ...
- jQuery.each() 的5个案例
1.基本的jQuery.each实例 看看 each() 函数是如何处理一个 jQuery 对象的.首先选取所有的a标签 并且打印出他们的href属性. 需要注意的是, 在 each() 当中使用 j ...
- (转)C#读取文件路径
//获取包含清单的已加载文件的路径或 UNC 位置. public static string sApplicationPath = Assembly.GetExecutingAssembly ( ) ...
- Asp 图形化报表
1 图形化的报表的优点 分析.统计业务数据 表现直观,漂亮,有震撼效果的图形化的方式展现业务数据 复杂的业务数据简单化 2 常用的报表组件 HighCharts:是纯js编写的图形化报表 水晶报表 ...
- DHCP租约时间工作原理
问题: 很多用户在使用路由器的DHCP服务器过程中都有一个疑问,DHCP有个设置项目是设置DHCP地址的租约时间,如果设置的比较短,是否会出现租约时间到了以后会重新去获取ip地址,造成用户断网? ...