标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10044 | Accepted: 3743 |
Description
Input
Output
Sample Input
4 4 *.*. .*** ***. ..*.
Sample Output
4
思路:建图,求出横着的board与竖着的board。若两个board相交则建边,那么边其实为‘*‘。二分图的最小顶点覆盖即为答案。
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int MAXN=1005; int n,m; char mz[MAXN][MAXN]; int set_x[MAXN][MAXN],lenx; int set_y[MAXN][MAXN],leny; vector<int> arc[MAXN]; void build_graph() { memset(set_x,0,sizeof(set_x)); memset(set_y,0,sizeof(set_y)); lenx=0; leny=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { int tag=0; if(mz[i][j]==‘*‘) { while(j<m&&mz[i][j]==‘*‘) { if(!tag) { tag=1; lenx++; } set_x[i][j]=lenx; j++; } } } } for(int j=0;j<m;j++) { for(int i=0;i<n;i++) { int tag=0; if(mz[i][j]==‘*‘) { while(i<n&&mz[i][j]==‘*‘) { if(!tag) { tag=1; leny++; } set_y[i][j]=leny; i++; } } } } for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(mz[i][j]==‘*‘) { int u=set_x[i][j]; int v=set_y[i][j]+lenx; arc[u].push_back(v); arc[v].push_back(u); } } } } int match[MAXN],vis[MAXN]; bool dfs(int u) { for(int i=0;i<arc[u].size();i++) { int to=arc[u][i]; if(!vis[to]) { vis[to]=1; int w=match[to]; if(w==-1||dfs(w)) { match[to]=u; match[u]=to; return true; } } } return false; } int max_flow() { int ans=0; memset(match,-1,sizeof(match)); for(int i=1;i<=lenx;i++) { if(match[i]==-1) { memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } } return ans; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<MAXN;i++) arc[i].clear(); for(int i=0;i<n;i++) { scanf("%s",mz[i]); } build_graph(); int res=max_flow(); printf("%d\n",res); } return 0; }
标签:
原文地址:http://www.cnblogs.com/program-ccc/p/5839766.html