hdu 5556 Land of Farms
来源:互联网 发布:牙签弩淘宝 编辑:程序博客网 时间:2024/06/16 18:08
Land of Farms
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 675 Accepted Submission(s): 220
Problem Description
Farmer John and his brothers have found a new land. They are so excited and decide to build new farms on the land. The land is a rectangle and consists of N×M grids. A farm consists of one or more connected grids. Two grids are adjacent if they share a common border, i.e. their Manhattan distance is exactly 1. In a farm, two grids are considered connected if there exist a series of adjacent grids, which also belong to that farm, between them.
Farmer John wants to build as many farms as possible on the new land. It is required that any two farms should not be adjacent. Otherwise, sheep from different farms would fight on the border. This should be an easy task until several ancient farms are discovered.
Each of the ancient farms also consists of one or more connected grids. Due to the respect to the ancient farmers, Farmer John do not want to divide any ancient farm. If a grid from an ancient farm is selected in a new farm, other grids from the ancient farm should also be selected in the new farm. Note that the ancient farms may be adjacent, because ancient sheep do not fight each other.
The problem is a little complicated now. Can you help Farmer John to find a plan with the maximum number of farms?
Farmer John wants to build as many farms as possible on the new land. It is required that any two farms should not be adjacent. Otherwise, sheep from different farms would fight on the border. This should be an easy task until several ancient farms are discovered.
Each of the ancient farms also consists of one or more connected grids. Due to the respect to the ancient farmers, Farmer John do not want to divide any ancient farm. If a grid from an ancient farm is selected in a new farm, other grids from the ancient farm should also be selected in the new farm. Note that the ancient farms may be adjacent, because ancient sheep do not fight each other.
The problem is a little complicated now. Can you help Farmer John to find a plan with the maximum number of farms?
Input
The first line of input contains a number T indicating the number of test cases (T≤200 ).
Each test case starts with a line containing two integersN and M , indicating the size of the land. Each of the following N lines contains M characters, describing the map of the land (1≤N,M≤10 ). A grid of an ancient farm is indicated by a single digit (0-9). Grids with the same digit belong to the same ancient farm. Other grids are denoted with a single character “.”. It is guaranteed that all test cases are valid.
Each test case starts with a line containing two integers
Output
For each test case, output a single line consisting of “Case #X: Y”. X is the test case number starting from 1. Y is the maximum number of new farms.
Sample Input
33 4..3.023..2112 3......4 411111..119911111
Sample Output
Case #1: 4Case #2: 3Case #3: 1
Source
2015ACM/ICPC亚洲区合肥站-重现赛(感谢中科大)
Recommend
wange2014 | We have carefully selected several similar problems for you: 6032 6031 6030 6029 6028
思路:当时我还没做过最大团问题。我先把联通块缩点然后把非相邻的两个点建边,然后就想不到怎么搞了。我只知道我这建的图的的最大完全子图是答案,但是不会求。之后找了题解就看到了最大团这个概念。最大团就是最大完全子图。然后我把模板套上去就好了。。。。。这里还有个定理:最大独立集合=补图的最大团=节点数-最大匹配数。下面给代码:
#include<bits/stdc++.h> using namespace std;typedef long long LL;const int maxn=15;char s[maxn][maxn];int n,m,vis[maxn][maxn],steparr[4][2]={-1,0,1,0,0,1,0,-1},vis2[maxn*maxn][maxn*maxn],num;const int N=105;bool G[N][N];int Max[N],Alt[N][N],ans;void dfsblock(int x,int y,char mark){if(x<0||x>=n||y<0||y>=m||vis[x][y]||s[x][y]!=mark)return;vis[x][y]=num;for(int i=0;i<4;i++){int nextx=x+steparr[i][0];int nexty=y+steparr[i][1];dfsblock(nextx,nexty,mark);}}void dfsedge(int x,int y){if(x<0||x>=n||y<0||y>=m||vis2[x][y])return;vis2[x][y]=1;for(int i=0;i<4;i++){int nextx=x+steparr[i][0];int nexty=y+steparr[i][1];G[vis[x][y]][vis[nextx][nexty]]=1;dfsedge(nextx,nexty);}}bool DFS(int cur,int tot){ if(!cur){ if(tot>ans){ans=tot;return 1;} return 0; } for(int i=1;i<=cur;i++){ if(cur-i+tot+1<=ans)return 0; int u=Alt[tot][i],nxt=0; if(Max[u]+tot<=ans)return 0; for(int j=i+1;j<=cur;j++) if(G[u][Alt[tot][j]])Alt[tot+1][++nxt]=Alt[tot][j]; if(DFS(nxt,tot+1))return 1; } return 0; }int MaxClique(){ ans=0,memset(Max,0,sizeof(Max)); for(int i=num-1;i;i--){ int cur=0; for(int j=i+1;j<num;j++) if(G[i][j])Alt[1][++cur]=j; DFS(cur,1); Max[i]=ans; } return ans;}int main(){int t;scanf("%d",&t);for(int tcase=1;tcase<=t;tcase++){memset(vis,0,sizeof(vis));memset(G,0,sizeof(G));memset(vis2,0,sizeof(vis2));ans=0;num=1;scanf("%d%d",&n,&m);for(int i=0;i<n;i++)scanf("%s",s[i]);for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(vis[i][j])continue;if(s[i][j]=='.')vis[i][j]=num++;else{dfsblock(i,j,s[i][j]);num++;}}}dfsedge(0,0);for(int i=1;i<num;i++){for(int j=1;j<num;j++){G[i][j]=!G[i][j];}}MaxClique();printf("Case #%d: %d\n",tcase,ans);}}
#include<bits/stdc++.h>using namespace std;#define N 102 int mx;//最大团数(要初始化为0) int x[N],tuan[N]; int can[N][N];//can[i]表示在已经确定了经选定的i个点必须在最大团内的前提下还有可能被加进最大团的结点集合 int num[N];//num[i]表示由结点i到结点n构成的最大团的结点数 bool g[N][N];//邻接矩阵(从1开始) int n,m; bool dfs(int tot,int cnt){ int i,j,k; if(tot == 0){ if(cnt > mx){ mx = cnt; for(i=0;i<mx;i++){ tuan[i] = x[i]; } return true; } return false; } for(i=0;i<tot;i++){ if(cnt + (tot-i) <= mx)return false; if(cnt + num[can[cnt][i]] <= mx)return false; k = 0; x[cnt] = can[cnt][i]; for(j=i+1;j<tot;j++){ if(g[can[cnt][i]][can[cnt][j]]){ can[cnt+1][k++] = can[cnt][j]; } } if(dfs(k,cnt+1))return false; } return false; } void MaxTuan(){ int i,j,k; mx = 1; for(i=n;i>=1;i--){ k = 0; x[0] = i; for(j=i+1;j<=n;j++){ if(g[i][j]){ can[1][k++] = j; } } dfs(k,1); num[i] = mx; } } const int maxn=20;struct Node{int x,y;Node(int _x=0,int _y=0):x(_x),y(_y){}};int id,dir[4][2]={-1,0,1,0,0,-1,0,1},ID[maxn][maxn];char mp[maxn][maxn];bool over(int x,int y){if(x<1||x>n||y<1||y>m)return true;return false;}void getid(int x,int y){if(ID[x][y]) return;if(mp[x][y]=='.') { ID[x][y]=id++; return; }else ID[x][y]=id++;queue<Node>Q;Q.push(Node(x,y));while(!Q.empty()){Node head=Q.front();Q.pop();for(int i=0;i<4;i++){int tx=head.x+dir[i][0],ty=head.y+dir[i][1];if(over(tx,ty)||ID[tx][ty]||mp[tx][ty]-mp[x][y]) continue;ID[tx][ty]=ID[x][y];Q.push(Node(tx,ty));}}}void init(){memset(ID,0,sizeof(ID));memset(g,0,sizeof(g)); id=1; mx=0;}int main(){ int T,cas=1; scanf("%d",&T);while(T--){ init();scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) getid(i,j); for(int i=1;i<=n;i++) {for(int j=1;j<=m;j++){for(int k=0;k<4;k++){int x=i,y=j;int tx=x+dir[k][0],ty=y+dir[k][1];if(over(tx,ty)) continue;if(ID[x][y]!=ID[tx][ty]) g[ID[x][y]][ID[tx][ty]]=g[ID[tx][ty]][ID[x][y]]=true;}}}n=id-1; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j]=!g[i][j]; MaxTuan(); printf("Case #%d: %d\n",cas++,mx); } return 0; }
阅读全文
0 0
- HDU 5556 Land of Farms
- hdu 5556 Land of Farms
- HDU 5556 Land of Farms 最大团
- hdu 5556 Land of Farms(二分图匹配)
- hdu 5556 Land of Farms(最大独立集)
- HDU 5556 Land of Farms(枚举 匈牙利)
- HDU 5556 Land of Farms(枚举+二分图匹配)
- hdu5556 Land of Farms
- hdu 5556 Land of Farms【思维+暴力枚举+最大独立集】好题!
- HDU-5556 Land of Farms(无向图的最大独立集)
- hdoj 5556 Land of Farms 二分图匹配
- HDU5556 Land of Farms 最大独立集
- HDU5556 Land of Farms(最大独立集)
- hdoj 5556 Land of Farms 【DFS + 最大独立集->补图最大团】
- HDU5556:Land of Farms(图的最大独立集 & 最大团)
- 【HDU5556 2015合肥赛区E】【最大团or二分图匹配】Land of Farms 不同编号不相邻条件下的最大农场数
- land of lisp 1
- The Land of Justice
- 剑指offer 10----计算一个整数二进制位中1的个数
- 大数除法之估商法
- [mooc]python网络爬虫与信息提取(实例一)
- stm32时钟配置
- Stirng-Stringbuild-Stringbuffer区别
- hdu 5556 Land of Farms
- 第三章:3.9 引用Django 认证登陆
- [GNU/Linux] Linux系统调用-文件操作(一)
- 485无线通信/数传模块_zigbee模块_RS485转ZigBee_顺舟智能
- java移位运算符:<<(左移)、>>(带符号右移)和>>>(无符号右移)。
- C++ 向量vector和模板的应用
- Suse11开启SSH密码登录
- spring中工厂模式和单例模式
- 第三章:3.9 关上窗户