[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 }
View Code

 

posted @ 2017-01-23 15:24  KingSann  阅读(146)  评论(0)    收藏  举报