【BZOJ4930】棋盘

Description

给定一个n×n的棋盘,棋盘上每个位置要么为空要么为障碍。定义棋盘上两个位置(x,y),(u,v)能互相攻击当前仅
当满足以下两个条件:
1:x=u或y=v
2:对于(x,y)与(u,v)之间的所有位置,均不是障碍。
现在有q个询问,每个询问给定ki,要求从棋盘中选出ki个空位置来放棋子,问最少互相能攻击到的棋子对数是多少?

Input

第一行一个整数n。
接下来输入一个n×n的字符矩阵,一个位置若为.,则表示这是一个空位置,若为#,则为障碍。
第n+2行输入一个整数q代表询问个数。
接下来q行,每行一个整数k,代表要放的棋子个数。
n ≤ 50, q ≤ 10000, k ≤ 棋盘中空位置数量

Output

输出共q行,每行代表对应询问的最少的互相能攻击到的棋子对数。

Sample Input

4
..#.
####
..#.
..#.
1 7

Sample Output

2

题解:还是集训原题~

如果你做过了BZOJ4554游戏那道题,还做过了修车,那么这道题岂不是很水?

如果没有障碍,那么我们显然是将网格按照行和列拆分,然后每行向每列连边,然后搞一搞,不过有障碍怎么办呢?

我们如果一行中有a段连续的障碍,我们认为每段障碍都将这行切成了两段,那么一共被切成了a+1段。类似地,每列也都被切成了好几段。那么我们得到了一堆行和一堆列,现在我们想在它们之间连边。

先考虑每一段行,在这个行中放一个棋子,产生的冲突数为0,再放1枚,冲突数+1,再放1枚,冲突数+2。。。那么我们显然可以考虑拆边。就有了建图方法:

设第i个行(被切过的)为hi,第j个列为rj,那么:

1.S -> hi 连若干条边,其中第k条费用为k-1,容量为1。
2.对于网格中的非障碍点(i,j),hi -> rj 费用为0,容量为1。
3.rj -> T 连若干条边,其中第k条费用为k-1,容量为1。

由于考试的时候我比较怂,所以写的动态加边,好像没什么必要~

练完边,跑完费用流后,再一起处理询问就好啦~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define P(A,B) ((A-1)*n+B)
using namespace std;
int n,m,S,T,cnt,sum,tot,mf,nx,ny;
char str[60][60];
int to[1000000],next[1000000],cost[1000000],flow[1000000],dis[10000],inq[10000],pe[10000],pv[10000],head[10000];
int ans[10000],bx[60][60],by[60][60],lx[10000],ly[10000],ux[10000],uy[10000];
queue<int> q;
void add(int a,int b,int c,int d)
{
to[cnt]=b,cost[cnt]=c,flow[cnt]=d,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,cost[cnt]=-c,flow[cnt]=0,next[cnt]=head[b],head[b]=cnt++;
}
int bfs()
{
memset(dis,0x3f,sizeof(dis));
dis[S]=0,q.push(S);
int i,u;
while(!q.empty())
{
u=q.front(),q.pop(),inq[u]=0;
for(i=head[u];i!=-1;i=next[i])
{
if(dis[to[i]]>dis[u]+cost[i]&&flow[i])
{
dis[to[i]]=dis[u]+cost[i],pe[to[i]]=i,pv[to[i]]=u;
if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
}
}
}
return dis[T]<0x3f3f3f3f;
}
int main()
{
//freopen("chess.in","r",stdin);
//freopen("chess.out","w",stdout);
scanf("%d",&n);
int i,j,a;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) scanf("%s",str[i]);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j==1||(str[i][j-2]=='#'&&str[i][j-1]=='.')) nx++;
if(str[i][j-1]=='.') lx[nx]++,bx[i][j]=nx;
}
}
for(j=1;j<=n;j++)
{
for(i=1;i<=n;i++)
{
if(i==1||(str[i-1][j-1]=='#'&&str[i][j-1]=='.')) ny++;
if(str[i][j-1]=='.') ly[ny]++,by[i][j]=ny,add(bx[i][j],by[i][j]+nx,0,1);
}
}
S=0,T=nx+ny+1;
for(i=1;i<=nx;i++) add(S,i,0,1);
for(i=1;i<=ny;i++) add(i+nx,T,0,1);
while(bfs())
{
int mf=1<<30;
for(i=T;i!=S;i=pv[i])
{
mf=min(mf,flow[pe[i]]);
if(i>nx&&i<T)
if(uy[i-nx]<ly[i-nx]) add(i,T,++uy[i-nx],1);
if(i<=nx&&i>S)
if(ux[i]<lx[i]) add(S,i,++ux[i],1);
}
tot+=mf*dis[T];
ans[sum+=mf]=tot;
for(i=T;i!=S;i=pv[i]) flow[pe[i]]-=mf,flow[pe[i]^1]+=mf;
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d",&a);
printf("%d\n",ans[a]);
}
return 0;
}

【BZOJ4930】棋盘 拆边费用流的更多相关文章

  1. 【BZOJ2245】[SDOI2011]工作安排 拆边费用流

    [BZOJ2245][SDOI2011]工作安排 Description 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被 ...

  2. bzoj 2597 剪刀石头布 —— 拆边费用流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2597 不合法的三个人之间的关系就是一个人赢了两次: 记 \( deg[i] \) 表示第 \ ...

  3. [WC2007]剪刀石头布——费用流

    比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...

  4. 【bzoj2245】[SDOI2011]工作安排 费用流

    题目描述 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被编号为1~m员工能够制造的产品种类有所区别.一件产品必须完整地由 ...

  5. 【bzoj4930】棋盘 费用流

    题目描述 给定一个n×n的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置(x,y),(u,v)能互相攻击当前仅 当满足以下两个条件: 1:x=u或y=v 2:对于(x,y)与(u,v)之间 ...

  6. [LOJ#6068]. 「2017 山东一轮集训 Day4」棋盘[费用流]

    题意 题目链接 分析 考虑每个棋子对对应的横向纵向的极大区间的影响:记之前这个区间中的点数为 \(x\) ,那么此次多配对的数量即 \(x\) . 考虑费用流,\(S\rightarrow 横向区间 ...

  7. BZOJ4930: 棋盘

    BZOJ4930: 棋盘 https://lydsy.com/JudgeOnline/problem.php?id=4930 分析: 基本上就是游戏那道题加上费用流了,所以没啥好说的. 记得两边都是拆 ...

  8. ACdream 1128 Maze(费用流)

    题目链接:http://acdream.info/problem?pid=1128 Problem Description wuyiqi陷入了一个迷宫中,这个迷宫是由N*M个格子组成的矩阵.每个格子上 ...

  9. 【 UVALive - 2197】Paint the Roads(上下界费用流)

    Description In a country there are n cities connected by m one way roads. You can paint any of these ...

随机推荐

  1. C源程序到可执行文件的四个过程

    C源程序到可执行文件的四个过程 1.预处理:预编译器执行.譬如C中的宏定义就是由预编译器处理,注释等也是由预编译器处理的 gcc -E -hello.c -o hello.i 2.编译:编译器来执行. ...

  2. 搭建Git本地服务器(转)

    http://www.cnblogs.com/trying/archive/2012/06/28/2863758.html 当前任务,学习中... 公司小范围用法:  服务器上做的: 在服务器上建立一 ...

  3. 2017.8.4 Creating Server TCP listening socket *:6379: bind: No such file or directory

    启动redis时出现如下错误:  解决办法:按顺序输入如下命令就可以连接成功. 1. redis-cli.exe 2. shutdown 3. exit 4. redis-server.exe 参考来 ...

  4. 在Hadoop监控页面怎样查看Hive的完整SQL

    如图.这里仅仅能看到简单的一段SQL.差点儿看不出详细在运行什么任务. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGFvemhhb2t1bg==/fo ...

  5. iOS开发 最近开发了蓝牙模块,在此记录总结一下(转载)

    1.基本概念 <1>中心者模式:常用的(其实99.99%)就是使用中心者模式作为开发,就是我们手机作为主机,连接蓝牙外设.由于开发只用到了中心者模式,所以我也只介绍中心者模式. <2 ...

  6. Vue-router(vue2.0)用法示例

    一.新建3个组件 1./src/components/post.vue <template> <div> hello world! this is POST! </div ...

  7. HDU 3732 Ahui Writes Word(多重背包)

    HDU 3732 Ahui Writes Word(多重背包) http://acm.hdu.edu.cn/showproblem.php? pid=3732 题意: 初始有N个物品, 每一个物品有c ...

  8. java代理ip有效检测

    java实现代理ip有效检测,依赖Apache的HttpClient   正式版:       /**        * 批量代理IP有效检测        *        * @param pro ...

  9. Mac 下Versions的 svn无法上传 .a 文件的问题

    Xcode自带的svn和Versions以及一些其它工具都默认ignore".a"文件. 解决办法有两个: 方法一:使用命令行添加文件([转]原文在这) 1.打开终端,输入cd,空 ...

  10. Android源码在线查看网址

    1 http://www.grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/