National Treasures HDU

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5;
const int maxn=1e3;
int e[N],ne[N],h[N],idx;
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
int n,m,xN,yN;
int link[N],num[maxn][maxn],mp[maxn][maxn];
bool vis[N];
int dir[][2] = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,0},{0,1},{1,0},{0,-1}};
 
bool dfs(int u) {
	for(int i=h[u]; i!=-1; i=ne[i]) {
		int t=e[i];
		if(!vis[t]) {
			vis[t]=true;
			if(link[t]==-1||dfs(link[t])) {
				link[t]=u;
				return true;
			}
		}
	}
	return false;
}

int max_match() {
	memset(link,-1,sizeof(link));
	int ans=0;
	for(int i=1; i<=xN; i++) {
		memset(vis,false,sizeof(vis));
		if(dfs(i)) ans++;
	}
	return ans;
}
bool check(int x,int y) {
	if(x<=0||y<=0||x>n||y>m||mp[x][y]==-1) return false;
	return true;
}

void init() {
	idx=0;
	memset(h,-1,sizeof h);
	xN=yN=0;
}

int main() {
	int cas=0;
	while(~scanf("%d%d",&n,&m)&&n&&m) {
		init();
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++)
				if((i+j)%2==0)
					num[i][j]=++xN;
				else
					num[i][j]=++yN;
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++)
				scanf("%d",&mp[i][j]);
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++) {
				if(mp[i][j]==-1) 
					continue;
				for(int k=0; k<12; k++) {
					if(mp[i][j]&(1<<k)) {
						int x=i+dir[k][0];
						int y=j+dir[k][1];
						if(!check(x,y))
							continue;
						if((i+j)%2==0)
							add(num[i][j],num[x][y]);
						else 
							add(num[x][y],num[i][j]);

					}
				}
			}
		printf("%d. %d
",++cas,max_match());
	}
	return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12402545.html