【luogu 3355】骑士共存问题

【【luogu 3355】骑士共存问题】题目描述
在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。
【luogu 3355】骑士共存问题
文章图片

棋盘上某些方格设置了障碍,骑士不得进入
对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击
输入格式:
第一行有 2 个正整数n 和 m (1<=n<=200, 0<=m
#include #include #include #include #define S 40003 #define T 40002 using namespace std; struct node{ int to,next,flow,from; }ed[1000100]; int head[41000],deep[41000],size=-1,ind[210][210],curr[41000],max_flow,n,m,k; int dx[]={1,1,-1,-1,2,2,-2,-2}; int dy[]={2,-2,2,-2,1,-1,1,-1}; int vis[210][210]; void add(int from,int to,int flow) { size++; ed[size].to=to; ed[size].from=from; ed[size].flow=flow; ed[size].next=head[from]; head[from]=size; } bool bfs() { queue q; memset(deep,0,sizeof(deep)); q.push(S); deep[S]=1; while(!q.empty()) { int u=q.front(); q.pop(); if(u==T) return true; for(int i=head[u]; ~i; i=ed[i].next) { int v=ed[i].to; if(!deep[v]&&ed[i].flow) { q.push(v); deep[v]=deep[u]+1; } } } return false; } int dfs(int u,int cur) { int rest=cur; if(u==T) return cur; for(int i=curr[u]; ~i; i=ed[i].next) { int v=ed[i].to; if(deep[v]==deep[u]+1&&ed[i].flow) { int new_flow=dfs(v,min(rest,ed[i].flow)); ed[i].flow-=new_flow; ed[i^1].flow+=new_flow; rest-=new_flow; if(ed[i].flow) curr[u]=i; if(!rest) break; } } if(cur==rest) deep[u]=-1; return cur-rest; } int dinic() { while(bfs()) { for(int i=0; i<=40010; i++) curr[i]=head[i]; max_flow+=dfs(S,1e9); } return max_flow; } int main() { memset(head,-1,sizeof(head)); int cnt=0; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) ind[i][j]=++cnt; for(int i=1; i<=m; i++) { int x,y; scanf("%d%d",&x,&y); vis[x][y]=1; } for(int x=1; x<=n; x++) { for(int y=1; y<=n; y++) { if(vis[x][y]) continue; if(((x+y)%2)==0) { for(int k=0; k<8; k++) { int tx=x+dx[k]; int ty=y+dy[k]; if(tx<1||tx>n||ty<1||ty>n) continue; add(ind[x][y],ind[tx][ty],1e9); add(ind[tx][ty],ind[x][y],0); } } } } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { if(vis[i][j]) continue; if(((i+j)%2)==0) add(S,ind[i][j],1),add(ind[i][j],S,0); else add(ind[i][j],T,1),add(T,ind[i][j],0); } printf("%d",n*n-dinic()-m); return 0; }

    推荐阅读