题目大意:

  传送门

  $n*n$的棋盘,有一些位置可以放棋子,有一些已经放了棋子,有一些什么都没有,也不能放,要求放置以后满足:第i行和第i列的棋子数相同,同时每行的棋子数占总数比例小于$\frac{A}{B}$。求最多可以放多少,无解则输出$impossible$。

题解:

   Orz一发大佬——传送门

  先把整张图放满,题目就转化为最少删多少点就合法。

  我们用$numx$来记录每行可以放的和已经放棋子总数,$numy$记录每列。从$S$向第i行连流量为$numx_i$的0费用边,从第j列向$T$连流量为$numy_j$的边。先不考虑怎么构建中间的图,在不考虑$\frac{A}{B}$的情况,我们需要判断流量合法的,我们可以让到$T$的边都满流意味着选了和没选的可以构成全集。

  我们对于可以放棋子的地方$(x,y)$,由第$x$行到第$y$列连$flow=1,cost=1$的边,表示将这个点删去的所需价值。

  考虑后一个限制。

  我们可以枚举每一行最多放置的棋子个数$f$,然后我们从第$i$行向第$i$列连一条$flow=f,cost=0$的边。表示第i行选了最多保留$f$个棋子,第$i$列保留棋子等同于这条边的流量,因为其他连向第$i$列的边都是要费用的,对第$i$行来讲其他的出边也是要费用的,而那些要费用的边就是删去的集合。

  然后判断一下当前解是否合法即可。

代码:

 #include "bits/stdc++.h"

 using namespace std;

 #define inf 0x3f3f3f3f

 inline int read() {
int s=,k=;char ch=getchar ();
while (ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while (ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
} const int N=; struct edges {
int v,cap,cost;edges *pair,*last;
}edge[N*N],*head[N];int cnt; inline void push(int u,int v,int cap,int cost) {
edge[++cnt]=(edges){v,cap,cost,edge+cnt+,head[u]},head[u]=edge+cnt;
edge[++cnt]=(edges){u,,-cost,edge+cnt-,head[v]},head[v]=edge+cnt;
} int S,T,n,fl,ans;
int piS,vis[N];
int cost; inline int aug(int x,int w) {
if (x==T) return cost+=1ll*piS*w,fl+=w,w;
vis[x]=true;
int ret=;
for (edges *i=head[x];i;i=i->last)
if (i->cap&&!i->cost&&!vis[i->v]) {
int flow=aug(i->v,min(i->cap,w));
i->cap-=flow,i->pair->cap+=flow,ret+=flow,w-=flow;
if (!w) break;
}
return ret;
} inline bool modlabel() {
static int d[N];
memset(d,0x3f,sizeof d);d[T]=;
static deque<int> q;q.push_back(T);
int dt;
while (!q.empty()) {
int x=q.front();q.pop_front();
for (edges *i=head[x];i;i=i->last)
if (i->pair->cap&&(dt=d[x]-i->cost)<d[i->v])
(d[i->v]=dt)<=d[q.size()?q.front():]
?q.push_front(i->v):q.push_back(i->v);
}
for (int i=S;i<=T;++i)
for (edges *j=head[i];j;j=j->last)
j->cost+=d[j->v]-d[i];
piS+=d[S];
return d[S]<inf;
} inline void solve() {
piS = cost = ;
while(modlabel())
do memset(vis,,sizeof vis);
while(aug(S, inf));
} char mp[N][N];
int numx[N],numy[N],A,B; int main() {
n=read(),A=read(),B=read();
T=n<<|;
int used=,sum=;
ans=-;
for (int i=;i<=n;++i) {
scanf("%s",mp[i]+);
for (int j=;j<=n;++j)
if(mp[i][j]=='C'||mp[i][j]=='.') {
++sum,++numx[i],++numy[j];
used+=mp[i][j]=='C';
}
}
for (int flow=;flow<=n;++flow) {
memset(head,,sizeof head);
cnt=;fl=;
for (int i=;i<=n;++i) {
push(S,i,numx[i],);
push(i+n,T,numy[i],);
push(i,i+n,flow,);
for (int j=;j<=n;++j)
if(mp[i][j]=='.')
push(i,j+n,,);
}
solve();
if (fl==sum&&flow*B<=(sum-cost)*A)
ans=max(ans,sum-cost);
}
if (ans==-) puts("impossible");
else printf("%d\n",ans-used);
}

【BZOJ 2673】[Wf2011]Chips Challenge的更多相关文章

  1. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  2. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  3. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  4. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  5. 【BZOJ 3958】 3958: [WF2011]Mummy Madness (二分+扫描线、线段树)

    3958: [WF2011]Mummy Madness Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 96  Solved: 41 Descripti ...

  6. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  7. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  8. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

  9. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

随机推荐

  1. html5中的网页结构

    一.html5中的大纲 在html5中,使用各种结构元素所描述出来的整个网页的层次结构,就是该网页的大纲.因此在组织这份大纲的时候,不能使用div元素,因为div元素只能当做容器,用在需要对网页中某个 ...

  2. 常见Map 及 ArrayList 是否有序总结

      常见Map 及 ArrayList 是否有序总结 说明:此处的排序 是指: 1: 往集合中插入元素的顺序与遍历元素的顺序的关系: 2: 往对象中插入元素否会根据元素的大小排序 public cla ...

  3. jquery作业

    1. 通过jquery动态的创建一个表格,随机生成(id自增,name随机2-3个中文汉字(10个姓,20个名字),age随机100以内整数)大于50小于100行的数据(用户对象:id,name,ag ...

  4. Js 浅克隆详解

    浅克隆:不仅赋值,而且赋予了内存地址深度克隆:赋值,内存地址不同var a = [1,2,3]; var b = a; a = [4,5,6]; alert(b); //[1,2,3] 面试时被问到这 ...

  5. MySQL 忘记root密码解决方法,基于Ubuntu 14.10

    忘记MySQL root密码解决方法,基于Ubuntu 14.10 忘了mysql密码,从网上找到的解决方案记录在这里. 编辑mysql的配置文件/etc/mysql/my.cnf,在[mysqld] ...

  6. Ocelot中文文档-Raft(实验功能不能用于生产环境)

    Ocelot最近整合了Rafty,这是我在去年一直研究的Raft的一个实现. 这个项目实验性非常强,所以在我认为它没问题之前,请不要在生产环境中使用Ocelot的这个功能. Raft是一种分布式一致性 ...

  7. Git忽略远程已存在的文件

    git设置本地忽略时远程上不存在本地忽略的文件,git将忽略.如果远程分支上存在这个文件,本地在设置ignore将不起作用.换句话说git本地忽略文件必须保证git的远程仓库分支上没有这个要忽略的文件 ...

  8. udp客户端收发数据流程

    1.创建客户端socket开始进行通讯.2.这时服务端应该先启动,并在知道服务端的ip以及端口号的时候才能进行通讯.3.本地不需要绑定ip以及端口号,在用此套接字对象发送消息的时候会自动分配活动端口( ...

  9. Django入门四之数据库相关

    1. 数据库设置 在settings.py中配置数据库 我首先使用的是sqlite3,所以配置如下 2. 数据库的数据结构定义 #blog/models.py #定义了一个表(Student),表里两 ...

  10. js基础--javaScript数据类型你都弄明白了吗?绝对干货

    欢迎访问我的个人博客:http://www.xiaolongwu.cn 数据类型的分类 JavaScript的数据类型分为两大类,基本数据类型和复杂数据类型. 基本数据类型:Null.Undefine ...