1526: Golden beans
Time Limit: 1 sec memory limit: 256 MB
Submit: 20 solved: 5 submitstatusweb Board
Description
Recently, James enjoys playing the golden bean game. There is an N * m checkboard, and each checkboard has a golden bean or none. If both adjacent grids have a golden bean, you can pick up the golden bean, and there is no gold beans in the two grids. If the distance between two grids is equal to 1, the two grids are adjacent. The goal of the game is to pick up the most gold beans as much as possible.
Input
The input in the first line is an integer T, indicating the number of test cases. Each test case contains two integers n, m (1 <= n, m <= 100), indicating the size of the Board. In the next n rows, the m integer (0 or 1) in each row indicates whether the grid contains beans.
Output
The maximum number of beans that can be picked up.
Sample Input
23 40 1 0 10 1 01 1 1 12 21 00 1
Sample output
60
Hint
Source
Submitstatusweb Board
Algorithm: maximum matching of a bipartite graph.
MARK: DFS [does not know how to search], and MLE is returned.
Idea: because the number of points is relatively large (a maximum of 10000 points may exist), the general Bipartite Graph Matching template can only solve the problem of less than 500,
The data is relatively weak, so the Hungary algorithm that uses kb God to use vector to implement the adjacent table (which can solve 1500 points in general) can pass.
1526 |
Accepted |
1692 |
28 |
C ++/edit |
2654 B |
19:42:19 |
#include<stdio.h>#include<string.h>#include<iostream>#include<vector>using namespace std;const int maxn = 10010;int linker[maxn];bool used[maxn];vector<int> map[maxn];int uN;bool find(int u){ for(int i = 0; i < map[u].size(); i++) { if(!used[map[u][i]]) { used[map[u][i]] = true; if(linker[map[u][i]] == -1 || find(linker[map[u][i]])) { linker[map[u][i]] = u; return true; } } } return false;}int hungary(){ int sum = 0; memset(linker,-1,sizeof(linker)); for(int u = 0; u < uN; u++) { memset(used,false,sizeof(used)); if(find(u)) sum++; } return sum;}int g[110][110];int hash[110][110];int main(){ int T; int n,m; int u,v; scanf("%d", &T); while(T--) { scanf("%d%d",&n,&m); uN = 0; for(int i = 0; i < maxn; i++) map[i].clear(); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { scanf("%d", &g[i][j]); if(g[i][j]) hash[i][j] = uN++; } } for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(g[i][j]) { u = hash[i][j]; if(i > 0 && g[i-1][j]) { v = hash[i-1][j]; map[u].push_back(v); map[v].push_back(u); } if(i < (n-1) && g[i+1][j]) { v = hash[i+1][j]; map[u].push_back(v); map[v].push_back(u); } if(j > 0 && g[i][j-1]) { v = hash[i][j-1]; map[u].push_back(v); map[v].push_back(u); } if(j < (m-1) && g[i][j+1]) { v = hash[i][j+1]; map[u].push_back(v); map[v].push_back(u); } } } } printf("%d\n", hungary()); } return 0;}
MLE code of the standard process
#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 105struct arc{ int j; arc * next;};struct vex{ int i; arc * first;};vex a[N*N];int map[N][N];int tu[10000][10000];int cov[N*N];int linker[N*N];int n,m;int hx[4]={0,-1,0,1};int hy[4]={-1,0,1,0};void dfs(int i,int j,int b){ int r; arc* p; if(b==0) { map[i][j]=2; for(r=0;r<4;r++) if(map[i+hx[r]][j+hy[r]]!=0) { p=(arc*)malloc(sizeof(arc)); p->j=(i+hx[r])*m+j+hy[r]; p->next=a[i*m+j].first; a[i*m+j].first=p; if(map[i+hx[r]][j+hy[r]]==1) dfs(i+hx[r],j+hy[r],1); } } else { map[i][j]=3; for(r=0;r<4;r++) if(map[i+hx[r]][j+hy[r]]==1) dfs(i+hx[r],j+hy[r],0); }}int dfs2(int k){ arc* p; int q; for(p=a[k].first;p!=NULL;p=p->next) if(!cov[p->j]) { q=linker[p->j]; linker[p->j]=k; cov[p->j]=1; if(q==-1||dfs2(q)) return 1; linker[p->j]=q; } return 0;}int work(){ int i,sum; for(i=0;i<m*n;i++) linker[i]=-1; for(i=0;i<n*m;i++) if(map[i/m][i%m]==2) { memset(cov,0,sizeof(cov)); dfs2(i); } sum=0; for(i=0;i<n*m;i++) if(linker[i]!=-1) sum++; return sum;}int main(){ int T,i,j,r,k,p; scanf("%d",&T); for(r=0;r<T;r++) { scanf("%d %d",&n,&m); for(i=0;i<m*n;i++) a[i].first=NULL; for(i=0;i<n;i++) for(j=0;j<m;j++) scanf("%d",&map[i][j]); for(i=0;i<n;i++) for(j=0;j<m;j++) if(map[i][j]==1) dfs(i,j,0); p=0; k=work(); printf("%d\n",k*2); } return 1;}