题目应该就是最大独立集了吧,没什么了,平面图求最大独立集需要/2的,

WQH说加直接+双向边考研过,结果真的过了,应该是匈牙利算法寻找的

时候更加快了吧。(方便找边)

 #include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#define N 207
using namespace std; const int lx[]={,,,,-,-,-,-};
const int ly[]={,,-,-,-,-,,}; int n,m;
int a[N][N],mark[N][N],du[N*N];
int cnt,head[N*N],next[N*N*N],rea[N*N*N];
int dui[N*N],flag[N*N]; void add(int u,int v){next[++cnt]=head[u],head[u]=cnt,rea[cnt]=v;}
bool dfs(int u)
{
for (int i=head[u];i!=-;i=next[i])
{
int v=rea[i];
if (flag[v]) continue;
flag[v]=;
if (!dui[v]||dfs(dui[v]))
{
dui[v]=u;
return ;
}
}
return ;
}
int main()
{
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
int num=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
scanf("%d",&a[i][j]);
mark[i][j]=(i-)*m+j;
if (a[i][j]) num++;
}
int x,y;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (a[i][j]==)
for (int k=;k<;k++)
{
x=i+lx[k],y=j+ly[k];
if(a[x][y]) continue;
if (x<=n&&x>=&&y>=&&y<=m) add(mark[i][j],mark[x][y]),add(mark[x][y],mark[i][j]);
}
memset(dui,,sizeof(dui));
int ans=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (a[i][j]==)
{
memset(flag,,sizeof(flag));
ans+=dfs(mark[i][j]);
}
ans=n*m-num-ans/;
printf("%d",ans);
}

其实还有更优秀的思想

(图太丑,不管了)

这里可以,将平面图分成这样的格点图,玩过国际象棋的都知道,马是一黑一白交替着走的,

也就说,在同种颜色中,马不会相互攻击,那只需要计算一种颜色中最大独立集就可以了,

这样就是先记录可以填的位置,然后只需要操作一种颜色,连边出去,连向另外一个集合,

这样匹配的就是无法共存点,这样就OK了。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define hash(A,B) ((A)*m-m+B)
#define ok(A,B) (A>=1&&A<=n&&B>=1&&B<=m&&!mp[A][B])
#define N 40010
#define M 500010 int m,n,flow,sum;
int cnt,head[N],vis[N],match[N],mp[][];
struct Edge{int to,nxt;}e[M];
int dis[][]={{-,},{-,-},{,},{,-},{-,},{-,-},{,},{,-}}; void adde(int u,int v)
{
e[++cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
bool dfs(int u,int flag)
{
for(int i=head[u];~i;i=e[i].nxt)
{
int v=e[i].to;
if(vis[v]==flag) continue;
vis[v]=flag;
if(!match[v]||dfs(match[v],flag))
{
match[v]=u;
return ;
}
}
return ;
}
int main()
{
cnt=;sum=;flow=;
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j) scanf("%d",&mp[i][j]);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
if(mp[i][j]) continue;sum++;
if((i^j)&)
{
for(int k=;k<;++k)
if(ok(i+dis[k][],j+dis[k][]))
{
adde(hash(i,j),hash(i+dis[k][],j+dis[k][]));
}
}
}
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
{
if(mp[i][j]) continue;
if((i^j)&)
{
int p=hash(i,j);
if(dfs(p,p)) flow++;
}
}
printf("%d\n",sum-flow);
return ;
}

BZOJ 4808 马 二分图最大独立集的更多相关文章

  1. BZOJ 4808: 马(二分图最大点独立集)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4808 题意: 思路: 这图中的两个马只能选一个,二选一,很像二分图吧,对能互吃的两个棋子连线,在所选 ...

  2. BZOJ4808马——二分图最大独立集

    题目描述 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗 称"蹩马腿"),则不允许走过去.为了简化问题, ...

  3. 解题:BZOJ 4808 马

    题面 以前写过的题,翻出来学习网络流写二分图匹配,因为复杂度更优秀,$Dinic$是$O(sqrt(n)m)$哒~ 原点向左部点连流量为$1$的边,左部点向对应右部点连流量为$1$的边,右部点向汇点连 ...

  4. bzoj 4808: 马【匈牙利算法】

    网格图黑白染色,然后能互相攻击到的点之间连边,跑匈牙利算法最大匹配,答案是好点个数-最大匹配(最大独立集) 注意pao的时候只从一种颜色的格子统计即可 #include<iostream> ...

  5. 【Codevs1922】骑士共存问题(最小割,二分图最大独立集转最大匹配)

    题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个 ...

  6. 长脖子鹿放置【洛谷P5030】二分图最大独立集变形题

    题目背景 众周所知,在西洋棋中,我们有城堡.骑士.皇后.主教和长脖子鹿. 题目描述 如图所示,西洋棋的“长脖子鹿”,类似于中国象棋的马,但按照“目”字攻击,且没有中国象棋“别马腿”的规则.(因为长脖子 ...

  7. HDU 3829 - Cat VS Dog (二分图最大独立集)

    题意:动物园有n只猫和m条狗,现在有p个小孩,他们有的喜欢猫,有的喜欢狗,其中喜欢猫的一定不喜欢狗,喜欢狗的一定不喜欢猫.现在管理员要从动物园中移除一些动物,如果一个小孩喜欢的动物留了下来而不喜欢的动 ...

  8. HDU3829(KB10-J 二分图最大独立集)

    Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)Total ...

  9. BZOJ3175:[TJOI2013]攻击装置(二分图最大独立集)

    Description 给定一个01矩阵,其中你可以在0的位置放置攻击装置.每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2), ...

随机推荐

  1. hihoCoder #1079 : 离散化 (线段树,数据离散化)

    题意:有一块宣传栏,高一定,给出长度,再给出多张海报的张贴位置,问还能见到几张海报(哪怕有一点被看到)?假设海报的高于宣传栏同高. 思路:问题转成“给出x轴上长为L的一条线段,再用n条线段进行覆盖上去 ...

  2. 洛谷 First Step (ファーストステップ) 3月月赛T1

    题目背景 知らないことばかりなにもかもが(どうしたらいいの?) 一切的一切 尽是充满了未知数(该如何是好) それでも期待で足が軽いよ(ジャンプだ!) 但我仍因满怀期待而步伐轻盈(起跳吧!) 温度差なん ...

  3. 自己开发的在线视频下载工具,基于Java多线程

    比如这个在线视频: 我们可以正常播放,但是找不到下载按钮. 打开Chrome开发者工具,在Network标签页里能看到很多网络传输请求: 随便看一个请求的响应,发现类型为video,大小为500多k. ...

  4. UVA - 12264 Risk (二分,网络流)

    题意比较坑,移动完以后的士兵不能再次移动,不然样例都过不了... 最小值最大满足决策单调性所以二分答案,跑网络流验证是否可行. 这种题重点在建图,为了保证只移动一次,拆点,一个入点一个出点,到了出点的 ...

  5. C04 模块化开发

    目录 模块化开发概述 函数概述 如何使用函数 字符串处理函数 模块化开发特点 模块化开发概述 概述 C语言是面向过程的语言,意味着编写C语言程序的时候,我们要像计算机一样思考如何设计程序. 模块化开发 ...

  6. 电脑上文件的后缀名被隐藏,把一个文本文件改成.bat时,默认打开的还是文本。

    1.打开文件夹,选择组织,点击“文件夹和搜索选项”,如图: 2.选择“查看”,找到“隐藏已知文件类型的扩展名”,不要勾选这一项,如图: 3.点击“确定”或者“应用”

  7. Noip2011提高组 聪明的质监员

    题目传送门 讲真,既然质监员这么聪明,为什么要让我们帮他设计程序? 所以还是叫ZZ的质检员吧 其实,我最想说的,不是这个题,而是这个\(\Sigma\)(一见 \(\Sigma\) 就懵逼系列) 这个 ...

  8. GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 (线段树)

    GSS4 - Can you answer these queries IV || luogu4145上帝造题的七分钟2 / 花神游历各国 GSS4 - Can you answer these qu ...

  9. Linux 永久修改主机名hostname

    前言: 由于最近用3台机器,经常切换导致有容易区别的需求. 故想修改主机名. 实验环境:Ubuntu 17 教程: 1. 使用hostname 命令先临时修改 sudo hostname your_n ...

  10. Python可变与不可变类型及垃圾回收机制

    1. 可变与不可变类型 1.1  可变类型 在id不变的情况下,value可以改变,则称之为可变类型.列表.字典与集合是可变的. l1 = [,,,,] print(id(l1)) l1[] = #改 ...