【bzoj4930】棋盘 费用流
题目描述
输入
输出
样例输入
4
..#.
####
..#.
..#.
1
7
样例输出
2
题解
费用流, bzoj4554 的强化版
按照那道题的思路,把相互影响的行和列的部分拿出来,同一个点的行部分和列部分之间连边。
不过这道题是固定棋子数,问最小的影响的棋子对数。
考虑,一个行或列的部分,如果存在k个棋子,那么相互影响的棋子对数为$\frac{k(k-1)}2$对(两个棋子之间隔着其它棋子也算相互影响)。
所以我们可以使用拆边法来解决,从S到行的部分、从列的部分到T连d条边,其中d为该部分的位置数。第i条边的费用为$\frac{i(i-1)}2-\frac{(i-1)(i-2)}2=i-1$。
然后跑费用流。在此过程中,由于每条增广路的容量必定为1,所以相当于每次多放置了一个棋子。这样我们可以只跑一次EK费用流即可预处理出所有答案,然后再$O(1)$回答。
时间有点长但可以过,可以动态加边来提高效率(这里懒了没有写)
#include <cstdio>
#include <cstring>
#include <queue>
#define N 6010
#define M 1200010
#define inf 0x3f3f3f3f
using namespace std;
queue<int> q;
int map[60][60] , bx[60][60] , tx , by[60][60] , ty , sx[N] , sy[N] , head[N] , to[M] , val[M] , cost[M] , next[M] , cnt = 1 , s , t , dis[N] , from[N] , pre[N] , ans[N];
char str[60];
void add(int x , int y , int v , int c)
{
to[++cnt] = y , val[cnt] = v , cost[cnt] = c , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , cost[cnt] = -c , next[cnt] = head[y] , head[y] = cnt;
}
bool spfa()
{
int x , i;
memset(from , -1 , sizeof(from));
memset(dis, 0x3f , sizeof(dis));
dis[s] = 0 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
if(val[i] && dis[to[i]] > dis[x] + cost[i])
dis[to[i]] = dis[x] + cost[i] , from[to[i]] = x , pre[to[i]] = i , q.push(to[i]);
}
return ~from[t];
}
void mincost()
{
int k = 0 , i;
while(spfa())
{
k ++ , ans[k] = ans[k - 1] + dis[t];
for(i = t ; i != s ; i = from[i]) val[pre[i]] -- , val[pre[i] ^ 1] ++ ;
}
}
int main()
{
int n , q , i , j , x;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%s" , str + 1);
for(j = 1 ; j <= n ; j ++ ) map[i][j] = (str[j] == '#');
}
for(i = 1 ; i <= n ; i ++ )
{
tx ++ ;
for(j = 1 ; j <= n ; j ++ ) bx[i][j] = tx , sx[tx] ++ , tx += map[i][j];
}
for(j = 1 ; j <= n ; j ++ )
{
ty ++ ;
for(i = 1 ; i <= n ; i ++ ) by[i][j] = ty , sy[ty] ++ , ty += map[i][j];
}
s = 0 , t = tx + ty + 1;
for(i = 1 ; i <= tx ; i ++ )
for(j = 0 ; j < sx[i] ; j ++ )
add(s , i , 1 , j);
for(i = 1 ; i <= ty ; i ++ )
for(j = 0 ; j < sy[i] ; j ++ )
add(i + tx , t , 1 , j);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
if(!map[i][j])
add(bx[i][j] , by[i][j] + tx , 1 , 0);
mincost();
scanf("%d" , &q);
while(q -- ) scanf("%d" , &x) , printf("%d\n" , ans[x]);
return 0;
}
【bzoj4930】棋盘 费用流的更多相关文章
- [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]
题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...
- 「2017 山东一轮集训 Day4」棋盘(费用流)
棋盘模型 + 动态加边 #include<cstdio> #include<algorithm> #include<iostream> #include<cs ...
- LOJ.6068.[2017山东一轮集训Day4]棋盘(费用流zkw)
题目链接 考虑两个\(\#\)之间产生的花费是怎样的.设这之间放了\(k\)个棋子,花费是\(\frac{k(k-1)}{2}\). 在\((r,c)\)处放棋子,行和列会同时产生花费,且花费和该行该 ...
- 【BZOJ4930】棋盘 拆边费用流
[BZOJ4930]棋盘 Description 给定一个n×n的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置(x,y),(u,v)能互相攻击当前仅 当满足以下两个条件: 1:x=u或y ...
- BZOJ4930: 棋盘
BZOJ4930: 棋盘 https://lydsy.com/JudgeOnline/problem.php?id=4930 分析: 基本上就是游戏那道题加上费用流了,所以没啥好说的. 记得两边都是拆 ...
- ACdream 1128 Maze(费用流)
题目链接:http://acdream.info/problem?pid=1128 Problem Description wuyiqi陷入了一个迷宫中,这个迷宫是由N*M个格子组成的矩阵.每个格子上 ...
- 洛谷P4003 无限之环(infinityloop)(网络流,费用流)
洛谷题目传送门 题目 题目描述 曾经有一款流行的游戏,叫做 Infinity Loop,先来简单的介绍一下这个游戏: 游戏在一个 n ∗ m 的网格状棋盘上进行,其中有些小方格中会有水管,水管可能在格 ...
- BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流
https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...
- 【BZOJ2668】[cqoi2012]交换棋子 费用流
[BZOJ2668][cqoi2012]交换棋子 Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列 ...
随机推荐
- Scanner-String-StringBuilder-API
1.能够明确API的使用步骤 1)打开帮助文档 2)点击显示,找到索引,看到输入框 3)你要找谁?在输入框里输入,然后回车 4)看包:java.lang下的类不需 ...
- Ubuntu安装新英伟达驱动出现问题解决方法
ERROR: The Nouveau kernel driver is currently in use by your system. This driver is incompatible wit ...
- NF!=1
NF表示列数,不等于1表示列数不为1列
- MySQL从服务配置文件
[mysql]port=3306socket=/var/lib/mysql/mysql.sockdefault-character-set = utf8mb4 [mysqld]server-id=2l ...
- 百度影棒安装apk方法
确保影棒和电脑接入家中同一WIFI中,开启影棒USB调试,手机端运行悟空助手或沙发管家等软件,之后无线推送需要安装的APK. 安装文件管理apk后,可以使用U盘安装.
- URAL 2048 Histroy(打表+模拟)
因为年历是400年一个循环节的,所以递推出一年的情况,然后递推处理出一个循环节的情况.对于询问,求一个类似前缀和的东西就好了. 跑出来和比样例小一,把A和B加一以后交后AC... 写得时候注意变量的定 ...
- Luogu P5352 Terrible Homework
神仙@TheLostWeak出的题,因为他最近没时间所以我先写一下sol(其实我也没什么时间) 作为一道简单的数据结构题想必大家都能看出必须用LCT维护信息吧 一个朴素的想法就是直接维护四种操作的值, ...
- winform中让显示的图片覆盖到父窗体保持父窗体的不可选中的状态,且任务栏中不会显示子窗体的任务选项
要求:为父窗体添加一个类似于加载等待的功能,当窗体点击备份时弹出且覆盖掉窗体 问题一产生:当为弹窗添加控件时,form.show();导致窗体卡死,控件变得透明化; 问题一分析:当窗体show();之 ...
- PAT (Basic Level) Practise (中文)-1030. 完美数列(25)
PAT (Basic Level) Practise (中文)-1030. 完美数列(25) http://www.patest.cn/contests/pat-b-practise/1030 给 ...
- Bootstrap 基本按钮
本章将通过实例讲解如何使用Bootstrap按钮,任何带有class.btn的元素都会继承圆角灰色默认按钮样式,但Bootstrap提供了一些选项来定义按钮的样式. 实例 <!DOCTYPE h ...