题目链接


考虑两个\(\#\)之间产生的花费是怎样的。设这之间放了\(k\)个棋子,花费是\(\frac{k(k-1)}{2}\)。

在\((r,c)\)处放棋子,行和列会同时产生花费,且花费和该行该连通块与该列该连通块当前有多少个有关。想到网络流就很简单了,建图比较简单,类似[[WC2007]剪刀石头布]。

点数写了3n2,其实2n2就够了...


//836ms	640K
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=55,N2=N*N*3,M=2e5+5,INF=0x3f3f3f3f; int S,T,mp[N][N],idr[N][N],idc[N][N],Enum,H[N2],nxt[M],to[M],cap[M],cost[M],q[10005],Ans[N*N],cur[N2],Cost,dis[N2];
bool vis[N2]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v,int w,int c)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w, cost[Enum]=c;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0, cost[Enum]=-c;
}
void NumberCol(int x,int y,int id)
{
int tx=x,cnt=1;
for(idc[x][y]=id; mp[x+1][y]; idc[++x][y]=id,++cnt);
for(x=tx; mp[x-1][y]; idc[--x][y]=id,++cnt);
for(int i=0; i<cnt; ++i) AE(id,T,1,i);
}
inline void Col(int x,int y,int id)
{
idr[x][y]=id, AE(id+1,idc[x][y],1,0);
}
void NumberRow(int x,int y,int id)
{
int ty=y,cnt=1;
for(Col(x,y,id); mp[x][y+1]; Col(x,++y,id),++cnt);
for(y=ty; mp[x][y-1]; Col(x,--y,id),++cnt);
for(int i=0; i<cnt; ++i) AE(id,id+1,1,i);
AE(S,id,cnt,0);
}
void Build(int n)
{
int tot=0; S=0, T=n*n*3+1, Enum=1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) if(mp[i][j]&&!idc[i][j]) NumberCol(i,j,++tot);
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j) if(mp[i][j]&&!idr[i][j]) NumberRow(i,j,++tot), ++tot;
}
bool SPFA()
{
static bool inq[N2];//N2!
static std::queue<int> q;
memset(dis,0x3f,T+1<<2);
q.push(S), dis[S]=0;
while(!q.empty())
{
int x=q.front(); q.pop(), inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(cap[i]&&dis[v=to[i]]>dis[x]+cost[i])
dis[v]=dis[x]+cost[i], !inq[v]&&(q.push(v),inq[v]=1);
}
return dis[T]<INF;
}
bool DFS(int x)
{
if(x==T) return 1;
vis[x]=1;
for(int &i=cur[x]; i; i=nxt[i])
if(cap[i]&&dis[to[i]]==dis[x]+cost[i]&&!vis[to[i]]&&DFS(to[i]))
return --cap[i],++cap[i^1],Cost+=cost[i],1;
return 0;
}
void Flow(int tot)
{
int flow=0;
while(SPFA())
{
memcpy(cur,H,T+1<<2), memset(vis,0,T+1);
while(flow<tot&&DFS(S)) Ans[++flow]=Cost;
if(flow>=tot) break;
}
} int main()
{
// freopen("A.in","r",stdin);
// freopen("A.out","w",stdout); int n=read();
for(int i=1; i<=n; ++i)
{
register char c=gc(); while(c!='.'&&c!='#') c=gc(); mp[i][1]=c=='.';
for(int j=2; j<=n; ++j) mp[i][j]=gc()=='.';
}
Build(n);
int m=read(),mx=0;
for(int i=1; i<=m; ++i) mx=std::max(mx,q[i]=read());
Flow(mx);
for(int i=1; i<=m; printf("%d\n",Ans[q[i++]])); return 0;
}

LOJ.6068.[2017山东一轮集训Day4]棋盘(费用流zkw)的更多相关文章

  1. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  2. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  3. loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流

    loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...

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

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

  5. LOJ 6068「2017 山东一轮集训 Day4」棋盘

    题意 一个 \(n\times n\) 的棋盘上面有若干障碍物. 定义两个棋子可以互相攻击当且仅当这两个棋子的横坐标或纵坐标相等而且中间不能隔着障碍物.(可以隔棋子) 有 \(q\) 次询问,每次询问 ...

  6. LOJ.6066.[2017山东一轮集训Day3]第二题(树哈希 二分)

    LOJ 被一件不愉快的小事浪费了一个小时= =. 表示自己(OI方面的)智商没救了=-= 比较显然 二分+树哈希.考虑对树的括号序列进行哈希. 那么每个点的\(k\)子树的括号序列,就是一段区间去掉距 ...

  7. LOJ.6060.[2017山东一轮集训Day1/SDWC2018Day1]Set(线性基)

    LOJ BZOJ 明明做过一道(最初思路)比较类似的题啊,怎么还是一点思路没有. 记所有元素的异或和为\(s\),那么\(x_1+x_2=x_1+x_1\ ^{\wedge}s\). \(s\)是确定 ...

  8. LOJ.6073.[2017山东一轮集训Day5]距离(可持久化线段树 树链剖分)

    题目链接 就是恶心人的,简单写写了...(似乎就是[HNOI2015]开店?) 拆式子,记\(dis_i\)为\(i\)到根节点的路径权值和,\(Ans=\sum dis_{p_i}+\sum dis ...

  9. LOJ.6074.[2017山东一轮集训Day6]子序列(DP 矩阵乘法)

    题目链接 参考yww的题解.本来不想写来但是他有一些笔误...而且有些地方不太一样就写篇好了. 不知不觉怎么写了这么多... 另外还是有莫队做法的...(虽然可能卡不过) \(60\)分的\(O(n^ ...

随机推荐

  1. java概念基础笔记整理

    1.构造方法没有类型,有类型的不是不叫构造方法. 2.一个类的的成员变量可以是java允许的任何数据类型,一个类可以把某个对象作为自己的一个成员变量,如果用这样的类创建对象,那么该对象中就会其他对象, ...

  2. 多线程相关-ThreadPoolExecutor

    应用层面: ThreadPoolExecutor: 创建多线程池执行器:new ThreadPoolExecutor(),创建方法最终都是走的以下这个构造方法: /** * Creates a new ...

  3. C++ Primer 笔记——union

    1.union是一种特殊的类.一个union可以有多个数据成员,但是在任意时刻,只有一个数据成员可以有值.当我们给union的某个成员赋值之后,该union的其他成员就变成未定义的状态了.分配给一个u ...

  4. XMind思维导图使用笔记

    首先新建一个空白的图 以组织结构图(向下)  为例 1.双击组织结构图 创建一个空白的页面 2.随便选择一个风格 这时候出现工作台 现在里面只有一个中心主题 正文部分开始 1.如果想要添加一个子主题 ...

  5. Eciplce ALT+/失效的解决方法

    最近公司电脑上的Eclipse没有了自动提示功能,也不是全部不提示,大多数情况下按下“alt+/”键还会产生提示,但是当我在java项目中邪main方法和syso的时候,“alt+/”则会失效,今天在 ...

  6. SQL Server表关联

    表关联:Hash.Nested Loops.Merge.这是实际算法,不是T-SQL中的inner/left/right/full/cross join.优化器会把这些T-SQL写法转换成上面的3种算 ...

  7. TypeScipt学习

    TypeScript具有类型系统,且是JavaScript的超集.它可以编译成普通的JavaScript代码. TypeScript支持任意浏览器,任意环境,任意系统并且是开源的.Ts主要用于解决那些 ...

  8. Centos7X部署Zabbix监控

    一:yum安装LAMP环境 zabbix-server端防火墙配置(可以选择iptables -F清空) iptables -A INPUT -m state --state NEW -m tcp - ...

  9. ELK 环境搭建1-Elasticsearch

    一.安装前准备 1.节点 192.168.30.41 192.168.30.42 192.168.30.43 2.操作系统: Centos7.5 3.安装包 a.java8: jdk-8u181-li ...

  10. BZOJ2527 [Poi2011]Meteors 整体二分 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686460.html 题目传送门 - BZOJ2527 题意 有$n$个国家. 太空里有$m$个太空站排成一个圆 ...