[POJ 2226] Muddy Fields
2018-03-09 20:17
211 查看
Description
如何放木板保证只覆盖到 ’*’ 而没有覆盖到 ’.’
Solution
(我太废了竟然想这题想了一个小时)考虑当前需要被覆盖的点 (x,y),假设有一块横着铺的木板 i ,一块竖着铺的木板 j,这两块木板同时经过了 (x,y),那么我们以横着铺的木板为左部点,竖着铺的木板为右部点,将这两个木板之间连一条边。问题就转化为了求二分图上的最小点覆盖。(因为每个要覆盖的点是一条边,要让每个点都被覆盖,等价于最小点覆盖)。
Code
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int pre[2505]; int head[2505]; bool vis[2505]; int mp[55][55]; int m,n,cnt,tot1,tot2,ans; int xx[55][55],yy[55][55]; struct Edge{ int to,nxt; }edge[250005]; void add(int x,int y){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } bool dfs(int now){ if(vis[now]) return 0; vis[now]=1; for(int i=head[now];i;i=edge[i].nxt){ int to=edge[i].to; if(!pre[to]||dfs(pre[to])){ pre[to]=now; return 1; } } return 0; } signed main(){ scanf("%d%d",&m,&n); for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ char ch;cin>>ch; if(ch=='*') mp[i][j]=1; else mp[i][j]=0; } } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(!mp[i][j]) continue; if(mp[i-1][j]) xx[i][j]=xx[i-1][j]; else xx[i][j]=++tot1; if(mp[i][j-1]) yy[i][j]=yy[i][j-1]; else yy[i][j]=++tot2; } } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(!mp[i][j]) continue; add(xx[i][j],yy[i][j]); } } for(int i=1;i<=tot1;i++){ memset(vis,0,sizeof vis); if(dfs(i)) ans++; } printf("%d",ans); return 0; }
相关文章推荐
- POJ - 2226 Muddy Fields 二分图 最小点覆盖
- POJ 2226 - Muddy Fields(二分图匹配)
- POJ-2226-Muddy Fields
- poj 2226 Muddy Fields(合理建图+二分匹配)
- POJ-2226 Muddy Fields 最小点集覆盖
- poj 2226 Muddy Fields(二分图——最小点覆盖)
- POJ 2226 Muddy Fields(最小点覆盖)
- POJ 2226 Muddy Fields(最小顶点覆盖)
- POJ 2226 Muddy Fields(匈牙利算法—最小点覆盖)
- POJ 2226 Muddy Fields(二分匹配-hungary)
- poj 2226 Muddy Fields(最小点集覆盖)
- POJ-2226-Muddy Fields
- POJ 2226 Muddy Fields 二分匹配
- poj 2226 Muddy Fields
- POJ 2226 Muddy Fields(二分匹配【最大流】)
- POJ 2226 Muddy Fields (最小点覆盖集,对比POJ 3041)
- poj 2226 Muddy Fields
- POJ 2226 Muddy Fields (最小点覆盖集,对比POJ 3041)
- poj 2226 Muddy Fields(最小点覆盖+巧妙构图)
- poj 2226 Muddy Fields 最大匹配