[bzoj1066]蜥蜴
把每一个柱子拆成一个top和一个bottom,然后连一条a[i][j]的容量,如果一个柱子到地图外面的距离小于等于d,那么就向T连一条INF的容量。
然后把S连向所有的蜥蜴(柱子的top),容量为1,最后把可以互相到达的柱子从bottom向top连INF的容量,最后跑最大流,记得用蜥蜴数减一下。
(由于不会写id(i,j)函数于是就用map了。。)

1 #include <iostream> 2 #include <algorithm> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <queue> 7 #include <map> 8 9 using namespace std; 10 11 int r,c,D; 12 char s1[100][100],s2[100][100]; 13 14 const int N=100000; 15 int head[N],rest[N],to[N],flow[N],tot,d[N],v[N],cur[N],S,T; 16 queue<int>q; 17 18 void ins(int u,int v,int f){ 19 to[tot]=v; 20 flow[tot]=f; 21 rest[tot]=head[u]; 22 head[u]=tot++; 23 } 24 int bfs(){ 25 memset(d,-1,sizeof(d)); 26 memset(v,0,sizeof(v)); 27 q.push(S); 28 d[S]=0; 29 v[S]=1; 30 while(q.size()){ 31 int fr=q.front();q.pop(); 32 for(int i=head[fr];i!=-1;i=rest[i]){ 33 int t=to[i]; 34 if(flow[i]&&!v[t]){ 35 v[t]=1; 36 d[t]=d[fr]+1; 37 q.push(t); 38 } 39 } 40 } 41 //printf("%d %d\n",v[T],d[T]); 42 return v[T]; 43 } 44 int dfs(int x,int a){ 45 if(x==T||!a)return a; 46 int ret=0,ff; 47 for(int &i=cur[x];i!=-1;i=rest[i]){ 48 int t=to[i]; 49 if(d[t]==d[x]+1&&(ff=dfs(t,min(a,flow[i])))>0){ 50 ret+=ff; 51 flow[i]-=ff; 52 flow[i^1]+=ff; 53 a-=ff; 54 if(!a)break; 55 } 56 } 57 return ret; 58 } 59 int mf(){ 60 int f=0; 61 while(bfs()){ 62 //printf("%d\n",f); 63 for(int i=S;i<=T;i++)cur[i]=head[i]; 64 f+=dfs(S,0x3f3f3f3f); 65 } 66 return f; 67 } 68 int tmp; 69 void add(int u,int v,int f){ins(u,v,f);ins(v,u,0);} 70 71 72 int M=0; 73 map<pair<int,int>,int>tp,bt; 74 #define IJ make_pair(i,j) 75 76 int Top(int i,int j){ 77 if(tp[IJ]==0)tp[IJ]=++M; 78 return tp[IJ]; 79 } 80 int Bot(int i,int j){ 81 if(bt[IJ]==0)bt[IJ]=++M; 82 return bt[IJ]; 83 } 84 85 vector<pair<int,int> >ps,ttt; 86 #define pow(a) ((a)*(a)) 87 int main(){ 88 memset(head,-1,sizeof(head)); 89 S=++M; 90 scanf("%d%d%d",&r,&c,&D); 91 for(int i=1;i<=r;i++)scanf("%s",s1[i]+1); 92 for(int i=1;i<=r;i++)scanf("%s",s2[i]+1); 93 for(int i=1;i<=r;i++){ 94 for(int j=1;j<=c;j++){ 95 if(s2[i][j]=='L'){ 96 tmp++; 97 add(S,Top(i,j),1); 98 } 99 if(s1[i][j]-'0'){ 100 if(i-D<=0||j-D<=0||i+D>r||j+D>c){ 101 //add(Bot(i,j),T,0x3f3f3f3f); 102 ttt.push_back(IJ); 103 Bot(i,j); 104 } 105 add(Top(i,j),Bot(i,j),s1[i][j]-'0'); 106 ps.push_back(IJ); 107 } 108 } 109 } 110 for(int i=0;i<ps.size();i++){ 111 for(int j=0;j<ps.size();j++){ 112 if(pow(ps[i].first-ps[j].first)+pow(ps[i].second-ps[j].second)<=pow(D)){ 113 //cout<<ps[i].first<<' '<<ps[i].second<<' '<<ps[j].first<<' '<<ps[j].second<<endl; 114 add(Bot(ps[i].first,ps[i].second),Top(ps[j].first,ps[j].second),0x3f3f3f3f); 115 } 116 } 117 } 118 T=++M; 119 for(int i=0;i<ttt.size();i++)add(Bot(ttt[i].first,ttt[i].second),T,0x3f3f3f3f); 120 printf("%d\n",tmp-mf()); 121 }