• CH6801 棋盘覆盖


    描述

    给定一个N行N列的棋盘,已知某些格子禁止放置。求最多能往棋盘上放多少块的长度为2、宽度为1的骨牌,骨牌的边界与格线重合(骨牌占用两个格子),并且任意两张骨牌都不重叠。N≤100。

    输入格式

    第一行为n,t(表示有t个删除的格子)
    第二行到t+1行为x,y,分别表示删除格子所在的位置
    x为第x行,y为第y列,行列编号从1开始。 

    输出格式

    一个数,即最多能放的骨牌数

    样例输入

    8 0

    样例输出

    32
            </article>
    

    题解

    1要素:每个格子只能被一张骨牌覆盖
    0要素:行号加列号的和奇偶性相同的格子之间没有边

    所以满足二分图二要素,跑二分图匹配即可。

    时间复杂度(O(n^4))

    co int N=100,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    int n,m,ans,f[N*N];
    bool b[N][N],v[N*N];
    vector<int> e[N*N];
    bool dfs(int x){
    	for(unsigned i=0;i<e[x].size();++i){
    		int y=e[x][i];
    		if(v[y]) continue;
    		v[y]=1;
    		if(f[y]==-1||dfs(f[y])){
    			f[y]=x;
    			return 1;
    		}
    	}
    	return 0;
    }
    int main(){
    	read(n),read(m);
    	while(m--) b[read<int>()-1][read<int>()-1]=1;
    	for(int i=0;i<n;++i)for(int j=0;j<n;++j)if(!b[i][j])
    		for(int k=0;k<4;++k){
    			int x=i+dx[k],y=j+dy[k];
    			if(0<=x&&x<n&&0<=y&&y<n&&!b[x][y])
    				e[i*n+j].push_back(x*n+y),e[x*n+y].push_back(i*n+j);
    		}
    	memset(f,-1,sizeof f);
    	for(int i=0;i<n;++i)for(int j=0;j<n;++j){
    		if((i^j)&1) continue;
    		memset(v,0,sizeof v);
    		ans+=dfs(i*n+j);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    定义serialVersionUID的作用与意义整理
    HttpClient学习整理
    Eclipse+TestNG搭建接口自动化测试框架
    Jmeter之Bean shell使用(一)
    吴军博士的《数学之美》(摘录)
    SqlServer—大话函数依赖与范式
    MySQL—FOREIGN KEY
    MYSQL-用户操作
    WAMPServer 默认安装启动后,图标显示橙黄色
    Linux time命令
  • 原文地址:https://www.cnblogs.com/autoint/p/10971362.html
Copyright © 2020-2023  润新知