网络流。
我一开始傻傻的将每条边与每一列连边,边权为联通块树,但是这样做是错的因为我们就在跑网络流中会忽略掉边和列的关系。
我们在做网络流题时一定要注意题目中给出的限制条件,一定要以限制条件建图!!!!
我们对每个联通块单独考虑,再在节点上对他所在的竖直联通块与水平联通块连线。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1000003; 4 char s[53][53]; 5 int n,m,t,sz; 6 int belx[53][53],bely[53][53]; 7 int result[2501]; 8 bool match[2501][2501],used[2501*2]; 9 bool dfs(int x) 10 { 11 for(int i=t+1;i<=sz;++i) 12 { 13 if(match[x][i]) 14 { 15 if(!used[i]) 16 { 17 used[i]=1; 18 if(!result[i]||dfs(result[i])) 19 { 20 result[i]=x; 21 return 1; 22 } 23 } 24 } 25 } 26 return 0; 27 } 28 int main() 29 { 30 //freopen("game.in","r",stdin); 31 //freopen("game.out","w",stdout); 32 scanf("%d%d",&n,&m); 33 for(int i=1;i<=n;++i) 34 scanf("%s",s[i]+1); 35 for(int i=1;i<=n;++i) 36 for(int j=1;j<=m;++j) 37 { 38 if(j==1||s[i][j-1]=='#') sz++; 39 belx[i][j]=sz; 40 } 41 t=sz; 42 for(int i=1;i<=m;++i) 43 for(int j=1;j<=n;++j) 44 { 45 if(j==1||s[j-1][i]=='#') sz++; 46 bely[j][i]=sz; 47 } 48 for(int i=1;i<=n;++i) 49 for(int j=1;j<=m;++j) 50 if(s[i][j]=='*') 51 match[belx[i][j]][bely[i][j]]=1; 52 int ans=0; 53 for(int i=1;i<=t;++i) 54 { 55 memset(used,0,sizeof used); 56 if(dfs(i)) ans++; 57 } 58 printf("%d ",ans); 59 }