乍一看与那个互不侵犯King很像,但这个数据范围就只能网络流了
我们可以发现只有黑的能攻击白的,白的能攻击黑的。
所以黑白相当于一个二分图
最小点独立集=总数-最小割(也就是说两个点里要至少留一个)
最小割=最小点覆盖=最大匹配
网络流建图求最大匹配即可
同时在做这题的过程中我发现对于网络流求最大匹配如果你一开始就能明确二分图的区分那么你可以建s->i,i->i~->i~->j,j->j~,j~->t
如果你并不能将他们区分开那么就要建s->i,i->j~,j~->t这种模型
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2005; 4 int head[N*N*2],d[N*N*2],ma[N][N]; 5 int n,m,cnt=-1,s,t; 6 struct node{ 7 int to,nex,w; 8 }e[2000005]; 9 int xx[8]={-1,-2,-1,-2,2,2,1,1}; 10 int yy[8]={2,1,-2,-1,-1,1,-2,2}; 11 void add(int x,int y,int w) 12 { 13 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w; 14 e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0; 15 } 16 queue<int>q; 17 bool bfs(int x,int y) 18 { 19 memset(d,-1,sizeof(d)); 20 d[x]=0;q.push(x); 21 while(!q.empty()) 22 { 23 int x=q.front();q.pop(); 24 for(int i=head[x];i!=-1;i=e[i].nex) 25 { 26 int y=e[i].to; 27 if(d[y]!=-1||!e[i].w)continue; 28 d[y]=d[x]+1;q.push(y); 29 } 30 } 31 return d[y]!=-1; 32 } 33 int dfs(int x,int w,int yy) 34 { 35 if(x==yy||!w)return w; 36 int s=0; 37 for(int i=head[x];i!=-1;i=e[i].nex) 38 { 39 int y=e[i].to; 40 if(!e[i].w||d[y]!=d[x]+1)continue; 41 int flow=dfs(y,min(w-s,e[i].w),yy); 42 if(!flow){ 43 d[y]=-1;continue; 44 } 45 e[i].w-=flow;e[i^1].w+=flow;s+=flow; 46 if(s==w)return s; 47 } 48 return s; 49 } 50 int dinic() 51 { 52 int ans=0; 53 while(bfs(s,t)) 54 { 55 ans+=dfs(s,1e9,t); 56 } 57 return ans; 58 } 59 int main() 60 { 61 int n,m;int tot=0; 62 scanf("%d%d",&n,&m); 63 memset(head,-1,sizeof(head)); 64 for(int i=1;i<=n;++i) 65 for(int j=1;j<=n;++j) 66 ma[i][j]=++tot; 67 for(int i=1;i<=m;++i) 68 { 69 int x,y; 70 scanf("%d%d",&x,&y); 71 ma[x][y]=0; 72 } 73 s=0;t=n*n*2+1;int p=n*n; 74 for(int i=1;i<=n;++i) 75 for(int j=(i%2)?1:2;j<=n;j+=2) 76 { 77 if(ma[i][j]) 78 { 79 add(s,ma[i][j],1); 80 for(int k=0;k<8;++k) 81 { 82 int nx=i+xx[k];int ny=j+yy[k]; 83 if((nx<1||nx>n||ny<1||ny>n)||ma[nx][ny]==0)continue; 84 add(ma[i][j],ma[nx][ny]+p,1); 85 } 86 } 87 } 88 for(int i=1;i<=n;++i) 89 for(int j=(i%2)?2:1;j<=n;j+=2) 90 if(ma[i][j]) 91 add(ma[i][j]+p,t,1); 92 int ans=dinic(); 93 printf("%d ",n*n-m-ans); 94 return 0; 95 }