bzoj 3175: [Tjoi2013]攻击装置
2017-09-10 16:57
405 查看
题解:
在n*n的棋盘的指定位置上放尽量多的马,使他们不能相互攻击。题解:
二分图最大独立集。因为太菜了,没做过这样对称的图论。
假如x能打到y,就连x到y。
于是显然图是对称的。
那么这时候的最大匹配/2,等价于黑白染色后的最大匹配。
然后最大独立集=总点数-最大匹配。
code:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; int yh[15]={-1,-2,1,2,-1,-2,1,2}; int yl[15]={-2,-1,-2,-1,2,1,2,1}; int n; char s[210]; int map[210][210],num=0,match[40010]; bool chw[40010]; struct node{ int y,next; }a[200010];int len=0,last[40010]; void ins(int x,int y) { a[++len].y=y; a[len].next=last[x];last[x]=len; } bool findma(int x) { for(int i=last[x];i;i=a[i].next) { int y=a[i].y; if(chw[y]) continue; chw[y]=true; if(match[y]==0||findma(match[y])) { match[y]=x; return true; } } return false; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s+1); for(int j=1;j<=n;j++) if(s[j]=='0') map[i][j]=++num; else map[i][j]=-1; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(map[i][j]!=-1) for(int k=0;k<8;k++) { int tx=i+yh[k],ty=j+yl[k]; if(tx<=0||tx>n||ty<=0||ty>n) continue; if(map[tx][ty]!=-1) ins(map[i][j],map[tx][ty]); } int ans=0; memset(match,0,sizeof(match)); for(int i=1;i<=num;i++) { memset(chw,false,sizeof(chw)); if(findma(i)) ans++; } printf("%d",num-ans/2); }
相关文章推荐
- BZOJ 3175: [Tjoi2013]攻击装置
- BZOJ3175 Tjoi2013 攻击装置(二分图匹配)
- BZOJ 3175: [Tjoi2013]攻击装置
- BZOJ3175 Tjoi2013 攻击装置(二分图匹配)
- bzoj 3175: [Tjoi2013]攻击装置 最大独立集 网络流
- BZOJ 3175 Tjoi2013 攻击装置 二分图最大匹配
- [bzoj 3175--TJOI2013]攻击装置
- BZOJ 3175: [Tjoi2013]攻击装置 二分图最大独立集
- [二分图最大独立集][BZOJ 3175][TJOI 2013]攻击装置
- bzoj 3175: [Tjoi2013]攻击装置
- BZOJ 3175 [Tjoi2013]攻击装置 二分图极大点独立集
- 【bzoj4808】马&&【bzoj3175】[Tjoi2013]攻击装置
- BZOJ_3175_[Tjoi2013]攻击装置_二分图匹配
- 【bzoj3175】[Tjoi2013]攻击装置
- [最小割]BZOJ 3175—— [Tjoi2013]攻击装置
- 【bzoj3175】 TJOI2013攻击装置 二分图最大独立集
- bzoj3175 [Tjoi2013]攻击装置 二分图匹配
- BZOJ3175 [Tjoi2013]攻击装置
- 【BZOJ 3175】 3175: [Tjoi2013]攻击装置(二分图匹配)
- [bzoj-3175][Tjoi2013]攻击装置 题解