[bzoj1735]泥泞的牧场

考虑木板一定都尽量长,对于每一个污泥,最多只有两种木板会覆盖它(横着和竖的),将这两块木板连边,意味着每一条边两端端点中一定有一个点要被选,即最小点覆盖=最大匹配数。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 105
 4 struct ji{
 5     int nex,to;
 6 }edge[N*N];
 7 int E,n,m,t,ans,head[N*N],id[N][N],vis[N*N],flag[N*N];
 8 char s[N][N];
 9 void add(int x,int y){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     head[x]=E++;
13 }
14 bool dfs(int k){
15     if (vis[k])return 0;
16     vis[k]=1;
17     for(int i=head[k];i!=-1;i=edge[i].nex){
18         int v=edge[i].to;
19         if ((!flag[v])||(dfs(flag[v]))){
20             flag[k]=v;
21             flag[v]=k;
22             return 1;
23         }
24     }
25     return 0;
26 }
27 int main(){
28     scanf("%d%d",&n,&m);
29     for(int i=0;i<n;i++,t++){
30         scanf("%s",s[i]);
31         for(int j=0;j<m;j++)
32             if (s[i][j]=='*')id[i][j]=t;
33             else t++;
34     }
35     memset(head,-1,sizeof(head));
36     for(int j=0;j<m;j++,t++)
37         for(int i=0;i<n;i++)
38             if (s[i][j]=='*')add(t,id[i][j]);
39             else t++;
40     for(int i=0;i<n;i++)
41         for(int j=0;j<m;j++)t=max(t,id[i][j]);
42     for(int i=1;i<=t;i++){
43         memset(vis,0,sizeof(vis));
44         if (!flag[i])ans+=dfs(i);
45     }
46     printf("%d",ans);
47 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249612.html