zoukankan      html  css  js  c++  java
  • AW372 棋盘覆盖

    题目地址


    易错点:

    • 可以双向加边这个一定要赞一个.
    • 在这种一次匹配则两个对象都被对方匹配上的题目中,应当在dfs成功时设置两个对象的match值为对方,即match[u]=v,match[v]=u.

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN=20000;
    struct Edge{
    	int from,to,nxt;
    }e[MAXN*100];
    int head[MAXN*100],edgeCnt=1;
    void addEdge(int u,int v){
    	e[++edgeCnt].from=u;
    	e[edgeCnt].to=v;
    	e[edgeCnt].nxt=head[u];
    	head[u]=edgeCnt;
    }
    bool vis[MAXN];
    int match[MAXN];
    bool dfs(int x){
    	for(int i=head[x];i;i=e[i].nxt){
    		int nowV=e[i].to;
    		if(vis[nowV])continue;
    		vis[nowV]=1;
    		if(!match[nowV]||dfs(match[nowV])){
    			match[nowV]=x;
    			match[x]=nowV;
    			return 1;
    		}
    	}
    	return 0;
    }
    int n;
    int getHash(int i,int j){
    	return (i-1)*n+j;
    }
    bool ban[110][110];
    int main(){
    	int t;
    	scanf("%d%d",&n,&t);
    	for(int i=1;i<=t;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		ban[x][y]=1;
    	}
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++){
    		if(ban[i][j])continue;
    		int nowV=getHash(i,j);
    		if(!ban[i-1][j]&&i-1>0)addEdge(nowV,getHash(i-1,j));
    		if(!ban[i+1][j]&&i+1<=n)addEdge(nowV,getHash(i+1,j));
    		if(!ban[i][j+1]&&j+1<=n)addEdge(nowV,getHash(i,j+1));
    		if(!ban[i][j-1]&&j-1>0)addEdge(nowV,getHash(i,j-1));
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++){
    		int nowV=getHash(i,j);
    		if(!match[nowV]){
    			memset(vis,0,sizeof(vis));
    			if(dfs(nowV))ans++;
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    【Leetcode】反转链表 II
    将博客搬至CSDN
    UVA 11021(概率)
    zoj
    Codeforces Round #227 (Div. 2) / 387C George and Number (贪心)
    点头(1163)
    fzu-2164 Jason's problem(数论)
    nyist --ACM组队练习赛(链接)
    nyoj-括号匹配(二)15---动态规划
    动态规划
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680594.html
Copyright © 2011-2022 走看看