[二分图最大独立集] BZOJ4808:马
棋盘01染色,然后把互相能打到的点连边,发现是个二分图。
二分图最大独立集 == 点数 −- 最大匹配数
Dinic练手…
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=40005,maxe=400005,flag[8][2]={{-1,-2},{-1,2},{1,-2},{1,2},{2,1},{-2,1},{2,-1},{-2,-1}};
int n,m,ans,cnt,N,S,T,map[205][205],c[205][205];
bool check(int x,int y){ return 1<=x&&x<=n&&1<=y&&y<=m&&!map[x][y]; }
struct Edge{int from,to,cap,flow;Edge(int t1=0,int t2=0,int t3=0,int t4=0){from=t1;to=t2;cap=t3;flow=t4;}
} Es[maxe];
int fir[maxn],pos[maxn],nxt[maxe],tot=1;
void add(int x,int y,int z){//printf("%d -> %d\n",x,y);Es[++tot]=Edge(x,y,z,0);nxt[tot]=fir[x]; fir[x]=tot;Es[++tot]=Edge(y,x,0,0);nxt[tot]=fir[y]; fir[y]=tot;
}
queue<int> Q;
int d[maxn],INF;
bool Bfs(){memset(d,63,sizeof(d)); INF=d[0];d[S]=0; Q.push(S);while(!Q.empty()){int x=Q.front(); Q.pop();for(int j=fir[x];j;j=nxt[j]) if(Es[j].cap>Es[j].flow&&d[Es[j].to]==INF){d[Es[j].to]=d[x]+1; Q.push(Es[j].to);}}return d[T]!=INF;
}
int Dfs_find(int x,int flw){if(x==T||flw==0) return flw;int res=0,t;for(int &j=pos[x];j;j=nxt[j])if(d[x]+1==d[Es[j].to]&&(t=Dfs_find(Es[j].to,min(flw,Es[j].cap-Es[j].flow)))>0){flw-=t; Es[j].flow+=t; Es[j^1].flow-=t; res+=t;if(flw==0) break;}return res;
}
int main(){freopen("bzoj4808.in","r",stdin);freopen("bzoj4808.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){c[i][1]=c[i-1][1]^1;for(int j=2;j<=m;j++) c[i][j]=c[i][j-1]^1;for(int j=1;j<=m;j++) scanf("%d",&map[i][j]);}N=n*m+2; S=n*m+1; T=n*m+2;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(!map[i][j]){cnt++;if(c[i][j]) add(S,(i-1)*m+j,1); else add((i-1)*m+j,T,1);}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(c[i][j]&&!map[i][j])for(int k=0;k<=7;k++) if(check(i+flag[k][0],j+flag[k][1])){int x=i+flag[k][0], y=j+flag[k][1];add((i-1)*m+j,(x-1)*m+y,1);}while(Bfs()){for(int i=1;i<=N;i++) pos[i]=fir[i];ans+=Dfs_find(S,1e9);}printf("%d\n",cnt-ans);return 0;
}
[二分图最大独立集] BZOJ4808:马相关推荐
- [二分图最大独立集] bzoj4808 马
bzoj4808 马:http://www.lydsy.com/JudgeOnline/problem.php?id=4808 把每个点和他所有能到达的点相连 最大独立集=总点数-最小覆盖集=总点数- ...
- 洛谷 - P3355 骑士共存问题(二分图最大独立集)
题目链接:点击查看 题目大意:给出一个n*n的棋盘,上面有m个点无法放置棋子,现在要求尽可能多的放 马,使得所有的马两两无法互相攻击,题目要求输出可以放置的最大数量 题目分析:二分图最大独立集的裸题, ...
- CH - 6901 骑士放置(二分图最大独立集-二分图最大匹配+奇偶拆点)
题目链接:点击查看 题目大意:给出一个n*m的棋盘,有t个点是禁止放棋子的,现在按照马走日的规则,问在互不影响的情况下最多能放多少个马 题目分析:这里首先简单介绍一下二分图最大独立集的定义: 通俗来讲 ...
- BZOJ4808: 马
BZOJ4808: 马 https://lydsy.com/JudgeOnline/problem.php?id=4808 分析: 黑白染色,求二分图最大匹配即可. 代码: #include < ...
- 最小割 ---- 二分图最大独立集(集合冲突模型) ---- 骑士共存 方格取数(网络流24题)
二分图独立集 定理: 二分图最大独立集=n - 二分图最大匹配 其实二分图独立集是特殊的一种最大权闭合子图.我们根据上文"收益"的思想,把选某个点的收益看为1,左部节点为正权点,右 ...
- 【二分图最大独立集】BZOJ4808[马]题解
题目概述 给出 n×mn\times m 的棋盘(有些位置有损坏),问最多能在其中放多少互不吃到的马(不能放在损坏位置中). 解题报告 NOIP2017前的最后一题QAQ. 首先将棋盘 0101 间隔 ...
- BZOJ4808马——二分图最大独立集
题目描述 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗 称"蹩马腿"),则不允许走过去.为了简化问题, ...
- BZOJ 4808(马-二分图最大独立集)
4808: 马 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 111 Solved: 46 [Submit][Status][Discuss] Des ...
- [BZOJ4808] 马(最大独立集,最大流)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4808 题意:其实就是找出一个点集的子集,使得这个子集中的点互不相连.求这个子集规模最大. ...
最新文章
- PCL深度图像(1)
- java什么叫内部对象,java – 函数对象的内部类中的变量/对象会发生什么?
- Android分享功能,微博、QQ、QQ空间等社交平台分享之入门与进阶
- 分治算法---汉诺塔
- 邪恶的Java技巧使JVM忘记检查异常
- sqoop导数据出现问题
- sqlserver查看索引_SQL Server页中行物理存储
- reactnative 获取定位_[RN] React Native 获取地理位置
- TTSR再次理解,主要是针对Texture Transformer TT的全部过程的一个梳理
- 负载均衡之LVS集群
- 软件测试开发人员的价值如何体现?
- R语言︱文本挖掘套餐包之——XML+SnowballC+tm包
- windows phone 切换多语言时,商店标题显示错误的问题
- 前端Svelte框架初体验
- solr6.3与MySQL结合使用
- tensorflow+k-means聚类 简单实现猫狗图像分类
- 【pandas】教程:1-处理什么样的数据
- Python Turtle绘图[难度2星]:奥运五环(用最简单的方法实现五环套接)
- 齐博x2如何新增自定义字段
- HotSpot虚拟机GC调优指南