问题描述

一个 \(N \times N\) 围棋棋盘,任意两个白子不相邻,你要加入若干个黑子并提出白子,最大化空格数目。

submit


题解

显然最终棋盘的局面不能够一个白子和它周围的空格都是空的,只能属于 「空」 或 「不空」 。

所以是个二分图。

二分图最大独立集=总点数-二分图最大匹配


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; //#define file
//#define local const int INF=0x3f3f3f3f; int n,S,T;
string s[52]; int Head[2507],Next[500007],to[500007],w[500007],tot=1; void addedge(int x,int y,int z){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
}
void add(int x,int y,int z){
addedge(x,y,z);addedge(y,x,0);
} void Init(void){
cin>>n;
for(int i=0;i<n;i++){
cin>>s[i];
cout<<s[i]<<endl;
}
} bool check(int x,int y){
return (x>=0&&x<n&&y>=0&&y<n);
} int id(int x,int y){
++x,++y;
return (x-1)*n+y;
} int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0}; int d[2507]; bool bfs(void){
memset(d,0,sizeof(d));
queue<int>q;q.push(S);d[S]=1;
while(q.size()){
int x=q.front();q.pop();
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(d[y]||!w[i]) continue;
d[y]=d[x]+1;q.push(y);
if(y==T) return true;
}
}
return false;
} int dfs(int x,int flow){
if(x==T) return flow;
int rest=flow;
for(int i=Head[x];i&&rest;i=Next[i]){
int y=to[i];
if(d[y]!=d[x]+1||!w[i]) continue;
int k=dfs(y,min(rest,w[i]));
if(!k) d[y]=0;
else w[i]-=k,w[i^1]+=k,rest-=k;
}
return flow-rest;
} int Dinic(void){
int t,res(0);
while(bfs()){
while(t=dfs(S,INF)) res+=t;
}
return res;
} void debug(void){
cout<<n<<endl;
for(int i=0;i<n;i++) cout<<s[i]<<endl; for(int i=2;i<=tot;i+=2){
printf("-- From %d to %d w = %d \n",to[i^1],to[i],w[i]);
}
printf("## S = %d , T = %d\n",S,T);
} int reduce; void Graph_build(void){
S=n*n+1,T=S+1;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(s[i][j]=='.') add(S,id(i,j),1);
else if(s[i][j]=='o') add(id(i,j),T,1);
else ++reduce;
for(int k=0;k<4;k++){
int nx=i+dx[k],ny=j+dy[k];
if(!check(nx,ny)) continue;
if(s[i][j]=='o'&&s[nx][ny]=='.') add(id(nx,ny),id(i,j),1);
}
}
}
// debug();
} int Work(void){
Graph_build();
return n*n-reduce-Dinic();
} #ifndef local
class FoxAndGo3{
public:
int maxEmptyCells(vector<string>vec){
n=vec[0].size();
for(int i=0;i<n;i++) s[i]=vec[i];
return Work();
}
};
#endif #ifdef local
int main(){
#ifdef file
freopen("hzlbn.in","r",stdin);
#endif
Init();
printf("%d\n",Work());
return 0;
}
#endif

TopCoder12808 「SRM594Medium」FoxAndGo3 二分图最大独立集的更多相关文章

  1. LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流

    题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...

  2. TopCoder12729 「SRM589Medium」GearsDiv1 二分图最小点覆盖

    问题描述 \(N\) 个齿轮每个齿轮有颜色(RGB),有些齿轮之间会咬合,你需要删除尽量少的齿轮并给每种颜色安排方向使得咬合齿轮不同向.问最多保留多少个齿轮.保证不存在两个相同颜色的齿轮咬合. sub ...

  3. 「THUWC 2017」随机二分图

    「THUWC 2017」随机二分图 解题思路 : 首先有一个 \(40pts\) 的做法: 前 \(20pts\) 暴力枚举最终的匹配是怎样的,check一下计算方案数,后 \(20pts\) 令 \ ...

  4. # 「NOIP2010」关押罪犯(二分图染色+二分答案)

    「NOIP2010」关押罪犯(二分图染色+二分答案) 洛谷 P1525 描述:n个罪犯(1-N),两个罪犯之间的仇恨值为c,m对仇恨值,求怎么分配使得两件监狱的最大仇恨值最小. 思路:使最大xxx最小 ...

  5. Loj #3057. 「HNOI2019」校园旅行

    Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...

  6. LOJ2557. 「CTSC2018」组合数问题

    LOJ2557. 「CTSC2018」组合数问题 这道题是我第一道自己做完的题答题.考场上面我只拿了41分,完全没有经验.现在才发现其实掌握了大概的思路还是不难. 首先模拟退火,通过了1,2,6,9, ...

  7. 「SCOI2015」小凸玩矩阵 解题报告

    「SCOI2015」小凸玩矩阵 我好沙茶啊 把点当边连接行和列,在外面二分答案跑图的匹配就行了 我最开始二分方向搞反了,样例没过. 脑袋一抽,这绝壁要费用流,连忙打了个KM 然后wa了,一想这个不是完 ...

  8. loj#2574. 「TJOI2018」智力竞赛 (路径覆盖)

    目录 题目链接 题解 代码 题目链接 loj#2574. 「TJOI2018」智力竞赛 题解 就是求可重路径覆盖之后最大化剩余点的最小权值 二分答案后就是一个可重复路径覆盖 处理出可达点做二分图匹配就 ...

  9. 「CH6901」骑士放置

    「CH6901」骑士放置 传送门 将棋盘黑白染色,发现"日"字的两个顶点刚好一黑一白,构成一张二分图. 那么我们将黑点向源点连边,白点向汇点连边,不能同时选的一对黑.白点连边. 当 ...

随机推荐

  1. 【Java Web开发学习】Spring构造器和属性注入

    测试类 public class Construct { private String address; private long phone; public Construct(String nam ...

  2. JQuery 操作checkbox

    获取checkbox选中的状态 deleteAll全选的name 1. $("input[name='deleteAll']").is(":checked") ...

  3. 设置td中的值自动换行

    style="word-wrap:break-word;word-break:break-all;"注意要设置td的宽度,否则没有用word-wrap:设置或检索当当前行超过指定容 ...

  4. python学习-os引入

    # 引入import os # 路径处理 -- 外部资源-os # 获取当前的工作路径workspace = os.getcwd() # os模块下的getcwd函数print(workspace) ...

  5. 快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

    一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...

  6. Python面向对象-类、实例的绑定属性、绑定方法和__slots__

    绑定属性 从之前的文章中,我们知道python是动态语言——实例可以绑定任意属性. 那如果实例绑定的属性和类的属性名一样的话,会是什么情况呢? >>> class Student(o ...

  7. Android binder流程简图

    前段时间因为一个bug,研究了一下android binder的大概流程,方便自己理解画了一个框图. 粗点线箭头是继承关系,细实线箭头是调用关系.

  8. C# 面向切面编程 AOP

    AOP(Aspect Oriented Programming) 面向切面编程 起源 引言  http://wayfarer.cnblogs.com/articles/241012.html AOP技 ...

  9. IPIP.net识别客户端真实访问地址,具体到国家,省,市

    这个IP库实测还是比较准确的,免费版的可以具体到国内城市,国外只能到国家名称,免费版的自己定期更新Ip数据库即可. 以下为C#调用代码 class Program { static void Main ...

  10. Socket实现简易聊天室,Client,Server

    package seday08; import java.io.BufferedWriter;import java.io.OutputStream;import java.io.OutputStre ...