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;能跳出去的地方建边,能互相跳的石柱建边。