BZOJ4554 HEOI2016游戏

网络流。

我一开始傻傻的将每条边与每一列连边,边权为联通块树,但是这样做是错的因为我们就在跑网络流中会忽略掉边和列的关系。

我们在做网络流题时一定要注意题目中给出的限制条件,一定要以限制条件建图!!!!

我们对每个联通块单独考虑,再在节点上对他所在的竖直联通块与水平联通块连线。

 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 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8185449.html