[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1735
[算法]
二分图最小覆盖
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 1010 struct edge { int to,nxt; } e[MAXN * MAXN]; int i,j,n,m,ans,cntx,cnty,tot; char mp[MAXN][MAXN]; int x[MAXN][MAXN],y[MAXN][MAXN]; int match[MAXN],head[MAXN]; bool visited[MAXN]; inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u] = tot; } inline bool hungary(int u) { int i,v; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (!visited[v]) { visited[v] = true; if (!match[v] || hungary(match[v])) { match[v] = u; return true; } } } return false; } int main() { scanf("%d%d",&n,&m); for (i = 1; i <= n; i++) scanf("%s",mp[i] + 1); for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { if (mp[i][j] == '*') { x[i][j] = ++cntx; while (j < m && mp[i][j + 1] == '*') { j++; x[i][j] = cntx; } } } } for (j = 1; j <= m; j++) { for (i = 1; i <= n; i++) { if (mp[i][j] == '*') { y[i][j] = ++cnty; while (i < n && mp[i + 1][j] == '*') { i++; y[i][j] = cnty; } } } } for (i = 1; i <= n; i++) { for (j = 1; j <= m; j++) { if (mp[i][j] == '*') addedge(x[i][j],y[i][j]); } } for (i = 1; i <= cntx; i++) { memset(visited,false,sizeof(visited)); if (hungary(i)) ans++; } printf("%d\n",ans); return 0; }