题目描述 Description
在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
上某些方格设置了障碍,骑士不得进入。
对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑
士,使得它们彼此互不攻击。
输入描述 Input Description
第一行有2 个正整数n 和m (1<=n<=200, 0<=m<n^2),
分别表示棋盘的大小和障碍数。接下来的m 行给出障碍的位置。每行2 个正整数,表示障
碍的方格坐标。
输出描述 Output Description
将计算出的共存骑士数输出
样例输入 Sample Input
3 2
1 1
3 3
样例输出 Sample Output
5
最大独立集=点数-最大匹配数(这题外加障碍数),黑书上讲的很明白了
单组数据测试的话可以用匈牙利算法,多组数据就必须用网络流来求最大匹配了
#include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <fstream> #include <numeric> #include <iomanip> #include <bitset> #include <list> #include <stdexcept> #include <functional> #include <utility> #include <ctime> using namespace std; #define PB push_back #define MP make_pair #define CLR(vis) memset(vis,0,sizeof(vis)) #define MST(vis,pos) memset(vis,pos,sizeof(vis)) #define MAX3(a,b,c) max(a,max(b,c)) #define MAX4(a,b,c,d) max(max(a,b),max(c,d)) #define MIN3(a,b,c) min(a,min(b,c)) #define MIN4(a,b,c,d) min(min(a,b),min(c,d)) #define PI acos(-1.0) #define INF 0x7FFFFFFF #define LINF 1000000000000000000LL #define eps 1e-8 typedef long long ll; typedef unsigned long long ull; const int dx[10]={1,1,2,2,-1,-1,-2,-2}; const int dy[10]={2,-2,1,-1,2,-2,1,-1}; int n,m; int mp[222][222],col[40010]; int link[40010],vis[40010]; int t; int dfs(int i,int j) { int x,y; for(int k=0;k<8;k++) { x=i+dx[k]; y=j+dy[k]; if(x<1 || y<1 || x>n || y>n || mp[x][y] || vis[(x-1)*n+y]==t) continue; vis[(x-1)*n+y]=t; int ii,jj; if(link[(x-1)*n+y]%n==0) ii=link[(x-1)*n+y]/n,jj=n; else ii=(link[(x-1)*n+y]/n)+1,jj=link[(x-1)*n+y]%n; if(!link[(x-1)*n+y] || dfs(ii,jj) ) { link[(x-1)*n+y]=(i-1)*n+j; return 1; } } return 0; } int main() { cin>>n>>m; int x,y; memset(mp,0,sizeof(mp)); for(int i=0;i<m;i++) { scanf("%d%d",&x,&y); mp[x][y]=1; } int sum=n*n; int tmp=0; for(int i=1;i<=sum;i++) { col[i]=tmp; tmp^=1; if( !(n&1) && !(i%n)) { tmp^=1; } } int ans=0; memset(link,0,sizeof(link)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(mp[i][j]) continue; t=(i-1)*n+j; if(col[t]) continue; if(dfs(i,j)) ans++; } } cout<<sum-(ans+m)<<endl; return 0; }