LUOGU 3355 24 Knight coexistence network flow problem

Copyright: https: //blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/90737835

title

LUOGU 3355
Title Description

in a n × n n \times n on a chess board squares, MA (Knight) can attack a checkerboard as shown in FIG. Some squares on a chessboard set up obstacles, Knight allowed to enter
Here Insert Picture Description
for a given n × n n \times n chess board and obstacles squares logo, the maximum number of knights can be placed on the board computing, so that they do not attack each other mutual

Input and output format
input format:

The first line has two positive integers n and m (1 <= n <= 200, 0 <= m <n2), each represent the size of the board and obstacles. The next position of m rows are given disorder. Each line of two positive integer representing the grid coordinates of the disorder.

Output formats:

The calculated number of output coexistence Knight

Input Output Sample
Input Sample # 1:

3 2
1 1
3 3

Output Sample # 1:

5

analysis

Simple meaning of the questions:

Seeking WITH OBSTACLES n × n n \times n chessboard how many horses can put that between any two can not attack each other.

It is one of the largest independent set of problems, routine. .

First, each horse can only attack with their different colors of plaid. Consider a bipartite graph. .

Routines or old, can attack each other between the lattice even one edge, and then find the maximum independent set bipartite graph can. .

Since (bipartite graph) = maximum independent set of points - the maximum matching , so we simply requires the largest match enough. .

Step detailed map building step and grid access issues are almost the same, this will not go into details. .

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e4+10,maxm=4e5+10,maxk=210,inf=1e9;
const int dx[]={-2,-1,1,2,2,1,-1,-2},dy[]={1,2,2,1,-1,-2,-2,-1};

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1, ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}

template<typename T>inline void write(T x)
{
	if (!x) { putchar('0'); return ; }
	if (x<0) putchar('-'),x=-x;
	T num=0,ch[20];
	while (x) ch[++num]=x%10+48,x/=10;
	while (num) putchar(ch[num--]);
}

int ver[maxm<<1],edge[maxm<<1],Next[maxm<<1],head[maxn],len=1;
inline void add(int x,int y,int z)
{
	ver[++len]=y,edge[len]=z,Next[len]=head[x],head[x]=len;
	ver[++len]=x,edge[len]=0,Next[len]=head[y],head[y]=len;
}

int s,t;
int dist[maxn];
inline bool bfs()
{
	queue<int>q;
	memset(dist,0,sizeof(dist));
	q.push(s);dist[s]=1;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		for (int i=head[x]; i; i=Next[i])
		{
			int y=ver[i];
			if (edge[i] && !dist[y])
			{
				dist[y]=dist[x]+1;
				if (y==t) return 1;
				q.push(y);
			}
		}
	}
	return 0;
}

inline int get(int x,int low)
{
	if (x==t) return low;
	int tmp=low;
	for (int i=head[x]; i; i=Next[i])
	{
		int y=ver[i];
		if (edge[i] && dist[y]==dist[x]+1)
		{
			int a=get(y,min(tmp,edge[i]));
			if (!a) dist[y]=0;
			edge[i]-=a;
			edge[i^1]+=a;
			if (!(tmp-=a)) break;
		}
	}
	return low-tmp;
}

int n,m;
inline int hash(int i,int j)
{
	return (i-1)*n+j;
}

bool ban[maxk][maxk];
int main()
{
	read(n);read(m);
	s=0,t=hash(n,n)+1;
	for (int i=1,x,y; i<=m; ++i) read(x),read(y),ban[x][y]=1;
	for (int i=1; i<=n; ++i)
		for (int j=1; j<=n; ++j)
		{
			if (ban[i][j]) continue;
			if ((i+j)&1)
			{
				add(s,hash(i,j),1);
				for (int k=0; k<8; ++k)
				{
					int fx=i+dx[k],fy=j+dy[k];
					if (fx<=0 || fx>n || fy<=0 || fy>n || ban[fx][fy]) continue;
					add(hash(i,j),hash(fx,fy),inf);
				}
			}
			else add(hash(i,j),t,1);
		}
	int ans=0;
	while (bfs()) ans+=get(s,inf);
	write(n*n-m-ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/huashuimu2003/article/details/90737835