[SCOI2007]蜥蜴(最大流)

最大流的入门题,比纯网络流的模板多了一个建模的过程。

首先建出源点并向所有的有蜥蜴的点建边(S,u,1),

之后把能互相到达的点建边,这里考虑一下容量改为多少,a[i][j]吗?

如果这样那么加入这个点(i,j)可以到达多个点该怎么办呢?

所以要拆点!把一个点拆成入点u和出点v,连边(u,v,a[i][j])即可。

接下来把所有能escape的点向汇点连边,最后跑最大流即可。

  1 #include<bits/stdc++.h>
  2 #define int long long
  3 using namespace std;
  4 const int N=250,INF=1e15;
  5 int sum,ans,tot=1,S,T,cnt,n,m,D,b[N][N],d[N*N],a[N][N],ma[N][N],head[N*N],to[N*N*100],ne[N*N*100],w[N*N*100];
  6 char ch[N];
  7 void add(int x,int y,int z)
  8 {
  9         to[++tot]=y;
 10         w[tot]=z;
 11         ne[tot]=head[x];
 12         head[x]=tot;
 13 }
 14 int dis(int x,int y,int l,int r)
 15 {
 16         return (x-l)*(x-l)+(y-r)*(y-r);
 17 }
 18 bool escape(int i,int j)
 19 {
 20         if(dis(i,j,i,0)<=D) return true;
 21         if(dis(i,j,i,m+1)<=D) return true;
 22         if(dis(i,j,0,j)<=D) return true;
 23         if(dis(i,j,n+1,j)<=D) return true;
 24         return false;
 25 }
 26 bool bfs(int x)
 27 {
 28         memset(d,0,sizeof(d));
 29         queue<int>q;
 30         q.push(x);
 31         d[x]=1;
 32         while(q.size())
 33         {
 34                 int y=q.front();
 35                 q.pop();
 36                 for(int i=head[y];i;i=ne[i])
 37                 {
 38                         int z=to[i];
 39                         if(!w[i]||d[z]) continue;
 40                         d[z]=d[y]+1;
 41                         if(z==T) return true;
 42                         q.push(z);
 43                 }
 44         }
 45         return false;
 46 }
 47 int dfs(int x,int in)
 48 {
 49         if(x==T) return in;
 50         int out=0;
 51         for(int i=head[x];i;i=ne[i])
 52         {
 53                 int y=to[i];
 54                 if(d[y]!=d[x]+1||!w[i]) continue;
 55                 int tmp=dfs(y,min(in,w[i]));
 56                 out+=tmp;
 57                 in-=tmp;
 58                 w[i]-=tmp;
 59                 w[i^1]+=tmp;
 60         }
 61         if(!out) d[x]=0;
 62         return out;
 63 }
 64 signed main()
 65 {
 66         //freopen("1.in","r",stdin);
 67         scanf("%lld%lld%lld",&n,&m,&D);
 68         D=D*D;
 69         cnt++;
 70         for(int i=1;i<=n;i++)
 71         {
 72                 scanf("%s",ch);
 73                 for(int j=1;j<=m;j++)
 74                 {
 75                         a[i][j]=ch[j-1]-'0';
 76                         if(a[i][j]) 
 77                         {
 78                                 ma[i][j]=++cnt;
 79                                 b[i][j]=++cnt;
 80                                 add(ma[i][j],b[i][j],a[i][j]);
 81                                 add(b[i][j],ma[i][j],0);
 82                         }
 83                 }
 84         }
 85         cnt++;
 86         S=1;T=cnt;
 87         for(int i=1;i<=n;i++)
 88         {
 89                 scanf("%s",ch);
 90                 for(int j=0;j<m;j++)
 91                 {
 92                         if(ch[j]=='L')
 93                         {
 94                                 sum++;
 95                                 add(S,ma[i][j+1],1);
 96                                 add(ma[i][j+1],S,0);
 97                         }
 98                 }
 99         }
100         for(int i=1;i<=n;i++)
101         {
102                 for(int j=1;j<=m;j++)
103                 {
104                         if(!a[i][j]) continue;
105                         for(int l=1;l<=n;l++)
106                         {
107                                 for(int r=1;r<=m;r++)
108                                 {
109                                         if(!a[l][r]||dis(i,j,l,r)>D) continue;
110                                         add(b[i][j],ma[l][r],INF);
111                                         add(ma[l][r],b[i][j],0);
112                                 }
113                         }
114                 }
115         }
116         for(int i=1;i<=n;i++)
117         {
118                 for(int j=1;j<=m;j++)
119                 {
120                         if(!a[i][j]||!escape(i,j)) continue;
121                         add(b[i][j],T,INF);
122                         add(T,b[i][j],0);
123                 }
124         }
125         while(bfs(S)) 
126         {
127                 ans+=dfs(S,INF);
128         }
129         printf("%lld",sum-ans);
130         return 0;
131 }
View Code

 

posted @ 2019-08-08 11:03  ATHOSD  阅读(100)  评论(0编辑  收藏  举报