1 #include<cstdio>
  2 #include<iostream>
  3 #define T 1001
  4 #define M 10005
  5 #define inf 0x7fffffff
  6 #include<cstring>
  7 using namespace std;
  8 int cnt=1,r,c,d,head[M],next[10*M],u[10*M],v[10*M],sum,f[25][25],d1[M],q[M],ans;
  9 char ch[50];
 10 int S(int a1,int a2)
 11 {
 12     return (a1-1)*c+a2;
 13 }
 14 void jia(int a1,int a2,int a3)
 15 {
 16     cnt++;
 17     u[cnt]=a2;
 18     v[cnt]=a3;
 19     next[cnt]=head[a1];
 20     head[a1]=cnt;
 21     return;
 22 }
 23 bool pan(int a1,int a2,int a3,int a4)
 24 {
 25     if(a1==a3&&a2==a4)
 26       return 0;
 27     if((a1-a3)*(a1-a3)+(a2-a4)*(a2-a4)>d*d)
 28       return 0;
 29     if(!f[a3][a4])
 30       return 0;
 31     return 1;
 32 }
 33 bool bfs()
 34 {
 35     memset(d1,0,sizeof(int)*M);
 36     int h=0,t=1;
 37     q[1]=0;
 38     d1[0]=1;
 39     for(;h<t;)
 40       {
 41         h++;
 42         int p=q[h];
 43         for(int i=head[p];i;i=next[i])
 44           if(!d1[u[i]]&&v[i])
 45             {
 46                 d1[u[i]]=d1[p]+1;
 47                 if(d1[T])
 48                   return 1;
 49                 t++;
 50                 q[t]=u[i];
 51             }
 52       }
 53     return 0;
 54 }
 55 int dinic(int s,int f)
 56 {
 57     if(s==T)
 58       return f;
 59     int rest=f;
 60     for(int i=head[s];i&&rest;i=next[i])
 61       if(v[i]&&d1[u[i]]==d1[s]+1)
 62         {
 63             int now=dinic(u[i],min(rest,v[i]));
 64             if(!now)
 65               d1[u[i]]=0;
 66             v[i]-=now;
 67             v[i^1]+=now;
 68             rest-=now;
 69         }
 70     return f-rest;  
 71 }
 72 int main()
 73 {
 74     scanf("%d%d%d",&r,&c,&d);
 75     for(int i=1;i<=r;i++)
 76       {
 77         scanf("%s",ch+1);
 78         for(int j=1;j<=c;j++)
 79           {
 80             int a1=ch[j]-'0';
 81             if(a1)
 82               {
 83                 f[i][j]=1;
 84                 jia(S(i,j),S(i,j)+r*c,a1);
 85                 jia(S(i,j)+r*c,S(i,j),0);
 86               }
 87           }
 88       }
 89     for(int i=1;i<=r;i++)
 90       {
 91         scanf("%s",ch+1);
 92         for(int j=1;j<=c;j++)
 93           if(ch[j]=='L')
 94             {
 95                 jia(0,S(i,j),1);
 96                 jia(S(i,j),0,0);
 97                 sum++;
 98             }
 99       }
100       for(int i=1;i<=d;i++)
101        for(int j=d+1;j<=r-d;j++)
102        {
103           jia(S(j,i)+r*c,T,inf);
104           jia(T,S(j,i)+r*c,0);
105           jia(S(j,c-i+1)+r*c,T,inf);
106           jia(T,S(j,c-i+1),0);
107        }
108     for(int i=1;i<=d;i++)
109        for(int j=1;j<=c;j++)
110        {
111           jia(S(i,j)+r*c,T,inf);
112           jia(T,S(i,j),0);
113           jia(S(r-i+1,j)+r*c,T,inf);
114           jia(T,S(r-i+1,j),0);
115        }
116     for(int i=1;i<=r;i++)
117       for(int j=1;j<=c;j++)
118         if(f[i][j])
119         for(int x=i-d;x<=i+d;x++)
120           for(int y=j-d;y<=j+d;y++)
121             if(pan(i,j,x,y))
122               {
123                 jia(S(i,j)+r*c,S(x,y),inf);
124                 jia(S(x,y),S(i,j)+r*c,0);
125               }
126     while(bfs())
127       sum-=dinic(0,0x7fffffff);
128     printf("%d\n",sum);
129     return 0;
130 }
131 

这是一个建图极其恶心的网络流 拆点 xi,xj。每个有石柱地方xi,xj,高。‘L'出S,xi,1;能跳出去的地方建边,能互相跳的石柱建边。

posted on 2016-03-01 22:42  xiyuedong  阅读(158)  评论(0编辑  收藏  举报