zoukankan      html  css  js  c++  java
  • Chessboard(二分图完备匹配)

    wa找不到原因,却是In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column。

    关键在于建立图的过程,本题是典型的黑白染色法建立图形,

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const int MAXN = 35*35;
    int vN, uN;
    bool g[MAXN][MAXN];
    bool clr[MAXN][MAXN];
    int xM[MAXN], yM[MAXN];
    bool chk[MAXN];
    int dx[] = {-1,0, 1, 0};
    int dy[] = {0, 1, 0, -1};
    
    bool searchPath(int u)
    {
    	int v;
    	for(v = 0; v < vN; v++)
    		if(g[u][v] && !chk[v])
    		{
    			chk[v] = true;
    			if(yM[v] == -1 || searchPath(yM[v])) 
    			{
    				yM[v] = u;
    				xM[u] = v;
    				return true;
    			}
    		}
    		return false;
    }
    
    int maxMatch()
    {
    	int u, ret = 0;
    	memset(xM, -1, sizeof(xM));
    	memset(yM, -1, sizeof(yM));
    	for(u = 0; u < uN; u++)
    		if(xM[u] == -1)
    		{
    			memset(chk,  false, sizeof(chk));
    			if(searchPath(u))ret++;
    		}
    		return ret;
    }
    bool check(int x, int y, int m, int n)
    {
    	return x>=0 && x < m && y>=0 && y<n;
    }
    int main()
    {
    	int m,n,k,a,b;
    	clr[0][0] = 1;
    	int i,j;
    	//给每一个部分染色 
    	for(i =1; i < MAXN; i++)clr[0][i] = !clr[0][i-1];
    	for(i = 1; i < MAXN; i++)
    		for(j = 0; j < MAXN; j++)
    			clr[i][j]= !clr[i-1][j];
    	//end 染色	
    		memset(g, 0, sizeof(g));
    		scanf("%d%d%d",&m, &n, &k);
    		int num[35][35];
    		memset(num, 0, sizeof(num));
    		
    		//标记坏点,将a,b转换为数组下标 
    		while(k--)
    		{
    			scanf("%d%d", &a, &b);
    			a--;
    			b--;
    			num[b][a] = -1;
    		}
    		
    		//统计出二分图矩阵的大小uN*vN 
    		int cnt = 0;
    		uN = vN = 0;
    		for(i = 0; i < m; i++)
    			for(j = 0; j < n; j++)
    			{
    				if(num[i][j] != -1)
    				{
    					if(clr[i][j]){num[i][j] = uN++;}
    					else {num[i][j] = vN++;}
    				}
    			}
    			
    			
    			if(uN != vN)
    			{
    				puts("NO");
    			}
    			else 
    			{//建二分图,找相互连接的边 
    				int ni,nj;
    				for(i = 0; i < m; i++)
    					for(j = 0; j < n; j++)
    						if(num[i][j]!=-1 && clr[i][j])
    						{
    							for(k = 0; k < 4; k++)
    							{
    								ni = i + dx[k];
    								nj = j + dy[k];
    								if(check(ni,nj, m,n) && num[ni][nj]!=-1 )
    								{
    									g[num[i][j]][num[ni][nj]] = 1;
    								}
    							}
    						}
    						
    				//如果可以完备匹配则成功,否则不成功		
    				if(maxMatch() == vN)puts("YES");
    				else puts("NO");
    			}
    			
    	system("pause");
    	return 0;
    }
    

      

      

     

  • 相关阅读:
    创建型模式
    建造者模式
    抽象工厂模式
    工厂方法模式
    原型模式
    [水]三个日常签到题
    [数]青蛙的约会&Strange function
    [水]三个数学的小技巧题
    Jquery Ajax的使用
    easyui学习记录:combotree的使用
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2486827.html
Copyright © 2011-2022 走看看