zoukankan      html  css  js  c++  java
  • 【CH6801】棋盘覆盖

    题目大意:给定一个 N*N 的棋盘,棋盘上有些位置不能防止任何东西,现用 1*2 的骨牌填充棋盘,问最多能铺多少块骨牌。

    题解:由于骨牌只能覆盖相邻的两个格子,那么按照对角线进行划分的格子可以保证一定不会被骨牌覆盖。因此,可以将骨牌看成边,每个格子可以与周围的四个合法的格子建立边。每个对角线上的点,以及隔着一组对角线的对角线之间不会被覆盖,因此可以作为二分图的点集合。建模之后直接用匈牙利算法进行匹配即可。

    代码如下

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define all(x) x.begin(),x.end()
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const int maxn=1e4+10;
    const int dx[]={0,1,0,-1};
    const int dy[]={1,0,-1,0};
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll sqr(ll x){return x*x;}
    inline ll read(){
    	ll x=0,f=1;char ch;
    	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
    	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
    	return f*x;
    }
    
    vector<int> G[maxn];
    int match[maxn];bool vis[maxn];
    int n,m,mpp[101][101],ans;
    
    inline bool right(int r,int c){return r>=1&&r<=n&&c>=1&&c<=n&&!mpp[r][c];}
    inline int get(int x,int y){return n*(x-1)+y;}
    
    void read_and_parse(){
    	n=read(),m=read();
    	for(int i=1;i<=m;i++){
    		int x=read(),y=read();
    		mpp[x][y]=1;
    	}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)if(!mpp[i][j]&&((i+j)&1))
    			for(int k=0;k<4;k++)
    				if(right(i+dx[k],j+dy[k])){
    					int x=get(i,j),y=get(i+dx[k],j+dy[k]);
    					G[x].pb(y),G[y].pb(x);
    				}
    }
    
    bool dfs(int u){
    	for(auto v:G[u])if(!vis[v]){
    		vis[v]=1;
    		if(!match[v]||dfs(match[v]))
    			return match[v]=u,1;
    	}
    	return 0;
    }
    
    void solve(){
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++){
    			if(((i+j)&1)||mpp[i][j])continue;
    			memset(vis,0,sizeof(vis));
    			if(dfs(get(i,j)))++ans;
    		}
    	printf("%d
    ",ans);
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
    
  • 相关阅读:
    CodeForces 706C Hard problem
    CodeForces 706A Beru-taxi
    CodeForces 706B Interesting drink
    CodeForces 706E Working routine
    CodeForces 706D Vasiliy's Multiset
    CodeForces 703B Mishka and trip
    CodeForces 703C Chris and Road
    POJ 1835 宇航员
    HDU 4907 Task schedule
    HDU 4911 Inversion
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10639092.html
Copyright © 2011-2022 走看看