• hdu 1507【Uncle Tom's Inherited Land*】


    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    vector<int> land[100];
    int link[100];
    bool vis[100];
    int g[110][110];
    bool vis2[100];
    int pond[100];
    int n,m,k;
    
    bool can(int x)
    {
    	int len = land[x].size();
    	for(int i = 0;i < len;i ++)
    	{
    		int t = land[x].at(i);
    		if(!vis[t])
    		{
    			vis[t] = true;
    			if(link[t] == -1 || can(link[t]))
    			{
    				link[t] = x;
    				return true;
    			}
    		}
    	}
    
    	return false;
    }
    
    int maxmatch(int count)
    {
    	int num = 0;
    	memset(link,-1,sizeof(link));
    	for(int i = 1;i <= count;i ++)
    	{
    		memset(vis,false,sizeof(vis));
    		if(can(i))
    			num ++;
    	}
    	/*for(int i = 1;i <= count;i ++)
    	{
    		if(link[i] != -1)
    			printf("link[%d]:%d\n",i,link[i]);
    	}*/
    
    	return num;
    }
    
    void print()
    {
    	memset(vis2,false,sizeof(vis2));
    	for(int i = 1;i <= n;i ++)
    	{
    		for(int j = 1;j <= m;j ++)
    		{
    			if(g[i][j]&&!vis2[g[i][j]]&&link[g[i][j]] != -1&&!vis2[link[g[i][j]]])
    			{
    				int ax = (g[i][j] + pond[g[i][j]] - 1)/m + 1;//pond的作用就在这里,将编号还原为矩形的一格一格编号
    				int ay = (g[i][j] + pond[g[i][j]]-1)%m+1;
    				int bx = (link[g[i][j]] + pond[link[g[i][j]]] - 1)/m +1;
    				int by = (link[g[i][j]] + pond[link[g[i][j]]]-1) % m+1;
    				vis2[g[i][j]] = true;//将访问过的点标记
    				vis2[link[g[i][j]]] = true;
    				printf("(%d,%d)--(%d,%d)\n",ax,ay,bx,by);
    			}
    		}
    	}
    
    	printf("\n");
    }
    
    int main()
    {
    	while(scanf("%d%d",&n,&m),n || m)
    	{
    		memset(g,-1,sizeof(g));
    		memset(pond,0,sizeof(pond));
    		scanf("%d",&k);
    		for(int i = 0;i < 55;i ++)
    		{
    			land[i].clear();
    		}
    		for(int i = 0;i < k;i ++)
    		{
    			int a,b;
    			scanf("%d%d",&a,&b);
    			g[a][b] = 0;
    		}
    
    		int t = 0;
    		int count = 1;
    		for(int i = 1;i <= n;i ++)
    		{
    			for(int j = 1;j <= m;j ++)
    			{
    				if(g[i][j] == 0)
    				{
    					t ++;
    				}
    				else
    				{
    					pond[count] = t;//记录land前面pond的个数
    					//printf("pond[%d]:%d\n",count,t);
    					g[i][j] = count ++;//给每个land编号
    				}
    			}
    		}
    
    		for(int i = 1;i <= n;i ++)
    		{
    			for(int j = 1;j <= m;j ++)
    			{
    				//printf("%d ",g[i][j]);
    				if(g[i][j] != 0)
    				{
    					if(i-1>0&&g[i-1][j] != 0)
    					{
    						land[g[i][j]].push_back(g[i-1][j]);
    					}
    					if(i +1 <=m && g[i+1][j] != 0)
    					{
    						land[g[i][j]].push_back(g[i + 1][j]);
    					}
    					if(j - 1> 0&& g[i][j -1] != 0)
    					{
    						land[g[i][j]].push_back(g[i][j-1]);
    					}
    					if(j + 1 <= n&&g[i][j + 1] != 0)
    					{
    						land[g[i][j]].push_back(g[i][j+1]);
    					}
    				}
    			}
    			//printf("\n");
    		}
    
    		printf("%d\n",maxmatch(count - 1) / 2);
    		print();
    	}
    
    	return 0;
    }
    

    一A,太兴奋了,(*^__^*) 嘻嘻……而且效率还蛮不错滴 15MS 292K。

    二分匹配来着,只不过题目要求我们输出匹配的方案

    本来之前打算来个暴力的,但是N*M可达1万,然后嘞,题目又说N*M-K<=50,就改变策略了,给不是池塘的land编号,并记录每个land前面的池塘数目(记录池塘的数目是方便输出的,题目要求我们输出匹配的行与列,反正land也就50个),这样编号的land最多也就50个了。

    可是就是还有人0ms过的,(~ o ~)~zZ崇拜

  • 相关阅读:
    web app变革之rem
    理解angularjs的作用域
    移动开发框架
    angularjs ng-repeat下验证问题
    10、长链接转短链接
    8、自定义菜单及菜单响应事件的处理
    9、多公众号集中管理
    7、消息管理-接收事件推送
    6、消息管理-普通消息接受处理
    5、用户和用户组管理-支持同步
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2497987.html
Copyright © 2020-2023  润新知