POJ 2226 二分图最小覆盖
2016-10-29 10:00
411 查看
题意:
思路:
把横着的连通块放在一个集合 竖着的放在一个集合
如果有交 就连边
求最小覆盖即可 (数值上等于最大匹配)
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 2555*2555 int n,m,first[2555],next[N],v[N],tot,cnt,change[55][55],changea[55][55],vis[2555],matched[2555],ans; char a[55][55]; void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;} bool dfs(int x){ for(int i=first[x];~i;i=next[i]){ if(!vis[v[i]]){ vis[v[i]]=1; if(!matched[v[i]]||dfs(matched[v[i]])){ matched[v[i]]=x; return 1; } } } return 0; } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ getchar(); for(int j=1;j<=m;j++) a[i][j]=getchar(); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]=='*'){ if(a[i][j-1]=='*') changea[i][j]=changea[i][j-1]; else changea[i][j]=++cnt; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]=='*'){ if(a[i-1][j]=='*') change[i][j]=change[i-1][j]; else change[i][j]=++cnt; add(changea[i][j],change[i][j]); } for(int i=1;i<=cnt;i++){ memset(vis,0,sizeof(vis)); if(dfs(i))ans++; } printf("%d\n",ans); }
相关文章推荐
- poj 2226 二分图 最小点覆盖 , 最大流
- poj 2226-二分图的最小顶点覆盖
- poj 2226 Muddy Fields(二分图最小点覆盖)
- poj 2226 二分图最小点覆盖
- POJ 2226 Muddy Fields【二分图最小点覆盖】
- POJ - 2226 Muddy Fields 二分图 最小点覆盖
- poj 2226 Muddy Fields(二分图——最小点覆盖)
- POJ 2226 二分图最小覆盖
- 二分图最小点覆盖 POJ 1325、2226、3041、3692、3829
- poj 2226 二分图 最小顶点覆盖 “草泥马”
- poj 2226 二分图 最小点覆盖 , 最大流
- POJ-2226-Muddy Fields-二分图-最小点覆盖
- poj 2226 Muddy Fields (转化成二分图的最小覆盖)
- [POJ] 2226 Muddy Fields(二分图最小点覆盖)
- poj 2226 二分图 最小点覆盖模型
- POJ 2226 二分图 最小点覆盖
- POJ 2226-Muddy Fields(二分图_最小点覆盖+神建图orz)
- poj 2226 二分图最小点集覆盖
- POJ 题目1422 Air Raid(二分图最小路径覆盖)
- 最小路径覆盖-二分图最大匹配 poj 1422