【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列 ...
随机推荐
- IOS开发之----详解在IOS后台执行
文一 我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间. 还有三种类型的可以运行在后以,1.音乐2.location 3.voip 文二 ...
- nmon安装和使用介绍
使用参考地址:百度中搜索 nmon 博客园 使用文档参考地址:http://nmon.sourceforge.net/pmwiki.php?n=Site.Documentation nmmon地址:h ...
- Bootstrap 入门到精通
介绍 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷.Bootstr ...
- Oracle错误(包括PL/SQL)集合与修复
+-----------------------------------------------------------------------+ | 在本篇随笔中,仅根据个人经验累积错误进行描述 ...
- Google Colab免费GPU使用教程(一)
一.前言 现在你可以开发Deep Learning Applications在Google Colaboratory,它自带免费的Tesla K80 GPU.重点是免费.免费!(国内可能需要tz) 这 ...
- Python协程函数
1 协程函数 1.1 协程函数理解 协程函数就是使用了yield表达式形式的生成器 def eater(name): print("%s eat food" %name) whil ...
- vue计算属性无法监听到数组内部变化
计算属性可以帮助我们简化代码,做到实时更新,不用再自己添加function去修改data. 首先看一下计算属性的基本写法(摘自官网) var vm = new Vue({ el: '#demo', d ...
- C语言中最常用标准库函数
标准头文件包括: <asset.h> <ctype.h> <errno.h> <float.h> <limits ...
- Python-DB接口规范
threadsafety 线程安全级别.threadsafety 这是一个整数, 取值范围如下: 0:不支持线程安全, 多个线程不能共享此模块 1:初级线程安全支持: 线程可以共享模块, 但不能共享连 ...
- Ukulele 调音
正常的持琴姿势时,从上到下依次是:4,3,2,1弦,音从上往下是:G,C,E,A: 3弦 - C - Do - D - Re 2弦 - E - Mi - F - Fa 4弦 - G -So 1弦 - ...