【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列 ...
随机推荐
- java 序列化Serializable 详解
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...
- Servlet和JSP之JSTL学习
JSTL JSTL就是JSP标准标签库(JavaServer Pages Standard Tag Library, JSTL)是一个定制标签库的集合,用来解决像遍历Map或集合.条件测试.XML处理 ...
- 解决Errno::ENOENT: No Such File or Directory - Jekyll ~ Octopress and El Capitan
参考http://schalkneethling.github.io/blog/2015/10/16/errno-enoent-no-such-file-or-directory-jekyll-oct ...
- App Transport Security has blocked a cleartext HTTP
打开info.plist源代码复制粘贴 <key>NSAppTransportSecurity</key> <dict> <!--Includ ...
- dp 20190618
C. Party Lemonade 这个题目是贪心,开始我以为是背包,不过也不太好背包,因为这个L都已经是1e9了. 这个题目怎么贪心呢?它是因为这里有一个二倍的关系,所以说val[i]=val[i- ...
- flask--Django 基本使用
#导入flaskfrom flask import Flask #创建应用 app = Flask(__name__) #创建根路径视图 @app.route('/') def hello_world ...
- 2890: C--去掉+86
2890: C--去掉+86 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 210 Solved: 91[Submit][Status][Web Bo ...
- 设置与使用SQL Server的字符集(Collation,即排序规则)
目录 目录 正确认识SQL Server的字符集 选择合适的SQL Server字符集 错误使用SQL Server的字符集 参考资料 正确认识SQL Server的字符集 SQL Server作为一 ...
- OpenCV2:第八章 界面事件
一.简介 OpenCV中提供了程序界面中的鼠标和键盘事件 二.鼠标事件 // 设置鼠标回调函数 void setMouseCallback ( const string& winname, ...
- Window命令行杀进程
Window命令行杀进程 1.查看任务列表 tasklist 2.以映象名杀 taskkill -t -f -im xx.exe 3.以进程杀死 taskkill /pid pid号 /f 4.针对w ...