您的位置:首页 > 其它

BZOJ1735: [Usaco2005 jan]Muddy Fields 泥泞的牧场

2017-09-13 14:00 423 查看

n<=50 * m<=50的地图,每块地‘*’表示一定要被填上,‘.’表示一定不能填上,用1*l或l*1,l自定,的板填起来,求最少几块板。

如果是做过那种“一炮打一列或一行,求几炮把地图上的点打掉”的二分图经典题,那就可以类比了。不过这里的行和列是基于联通块的,所以预处理出行联通块和列联通块并编号,一个点选,意味着它对应的行联通块和列联通块至少选一个,因此连边。

1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<algorithm>
5 //#include<iostream>
6 using namespace std;
7
8 int n,m;
9 bool mp[55][55];
10 char s[55];int belx[55][55],bely[55][55],cntx=0,cnty=0;
11 #define maxn 5011
12 #define maxm 5011*4
13 const int inf=0x3f3f3f3f;
14 struct Network
15 {
16     struct Edge{int to,next,cap,flow;}edge[maxm];int first[maxn],le;
17     Network() {le=2;memset(first,0,sizeof(first));}
18     int n,s,t;
19     void in(int x,int y,int cap) {Edge &e=edge[le];e.to=y;e.cap=cap;e.flow=0;e.next=first[x];first[x]=le++;}
20     void insert(int x,int y,int cap) {in(x,y,cap);in(y,x,0);}
21     int que[maxn],head,tail;int dis[maxn],cur[maxn];
22     bool bfs()
23     {
24         que[head=(tail=1)-1]=s;
25         memset(dis,0,sizeof(dis));dis[s]=1;
26         while (head!=tail)
27         {
28             const int now=que[head++];
29             for (int i=first[now];i;i=edge[i].next)
30             {
31                 const Edge &e=edge[i];
32                 if (e.cap>e.flow && !dis[e.to])
33                 {
34                     dis[e.to]=dis[now]+1;
35                     que[tail++]=e.to;
36                 }
37             }
38         }
39         return dis[t];
40     }
41     int dfs(int x,int a)
42     {
43         if (x==t || !a) return a;
44         int flow=0,f;
45         for (int &i=cur[x];i;i=edge[i].next)
46         {
47             Edge &e=edge[i];
48             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
49             {
50                 flow+=f;
51                 e.flow+=f;
52                 edge[i^1].flow-=f;
53                 a-=f;
54                 if (!a) break;
55             }
56         }
57         return flow;
58     }
59     int Dinic(int s,int t)
60     {
61         this->s=s,this->t=t;
62         int ans=0;
63         while (bfs())
64         {
65             for (int i=1;i<=n;i++) cur[i]=first[i];
66             ans+=dfs(s,inf);
67         }
68         return ans;
69     }
70 }g;
71 int main()
72 {
73     scanf("%d%d",&n,&m);
74     for (int i=1;i<=n;i++)
75     {
76         scanf("%s",s+1);
77         for (int j=1;j<=m;j++)
78             mp[i][j]=s[j]=='*';
79     }
80     for (int j=1;j<=m;j++)
81     {
82         belx[1][j]=mp[1][j]?++cntx:0;
83         for (int i=2;i<=n;i++)
84             if (mp[i][j])
85             {
86                 if (mp[i-1][j]) belx[i][j]=cntx;
87                 else belx[i][j]=++cntx;
88             }
89             else belx[i][j]=0;
90     }
91     for (int i=1;i<=n;i++)
92     {
93         bely[i][1]=mp[i][1]?++cnty:0;
94         for (int j=2;j<=m;j++)
95             if (mp[i][j])
96             {
97                 if (mp[i][j-1]) bely[i][j]=cnty;
98                 else bely[i][j]=++cnty;
99             }
100             else bely[i][j]=0;
101     }
102     g.n=cntx+cnty+2;int s=g.n-1,t=g.n;
103     for (int i=1;i<=n;i++)
104         for (int j=1;j<=m;j++)
105             if (mp[i][j]) g.insert(belx[i][j],bely[i][j]+cntx,1);
106     for (int i=1;i<=cntx;i++) g.insert(s,i,1);
107     for (int i=cntx+1;i<=cntx+cnty;i++) g.insert(i,t,1);
108     printf("%d\n",g.Dinic(s,t));
109     return 0;
110 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: