首页 > 代码库 > 【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

【bzoj1066】: [SCOI2007]蜥蜴

把石柱拆点,流量为高度

然后S与蜥蜴连流量1的边

互相能跳到的石柱连inf的边

石柱能到边界外的和T连inf的边

然后跑dinic就好了

技术分享
  1 /* http://www.cnblogs.com/karl07/ */
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <algorithm>
  7 #include <queue>
  8 using namespace std;
  9 const int N=1000000;
 10 const int inf=1e9;
 11 struct edge{
 12     int next,to,c;
 13 }e[N+1];
 14 int ade=1,S=1,T=2,n,m,c,d,CNT=2;
 15 int first[N+1],dis[N+1],now[N+1],mp[25][25],I[25][25],O[25][25];
 16 queue <int> Q;
 17 
 18 void addedge(int x,int y,int cap){
 19     e[++ade].next=first[x];
 20     e[ade].to=y;
 21     e[ade].c=cap;
 22     first[x]=ade;
 23     e[++ade].next=first[y];
 24     e[ade].to=x;
 25     e[ade].c=0;
 26     first[y]=ade;
 27 }
 28 
 29 #define s e[x].to
 30 #define cap e[x].c
 31 #define CAP e[x^1].c
 32 bool bfs(){
 33     for (int i=1;i<=CNT;i++) dis[i]=inf;
 34     Q.push(S);
 35     dis[S]=0;
 36     while (!Q.empty()){
 37         int p=Q.front();
 38         Q.pop();
 39         for (int x=first[p];x;x=e[x].next){
 40             if (dis[s]>dis[p]+1 && cap>0){
 41                 Q.push(s);
 42                 dis[s]=dis[p]+1;
 43             }
 44         }
 45     }
 46     return dis[T]!=inf;
 47 }
 48 
 49 int dfs(int p,int mf){
 50     if (p==T) return mf;
 51     for (int x=now[p];x;x=e[x].next){
 52         now[p]=x;
 53         if (dis[s]==dis[p]+1 && cap>0){
 54             int f=dfs(s,min(mf,cap));
 55             if (f){
 56                 cap-=f;
 57                 CAP+=f;
 58                 return f;
 59             }
 60         }
 61     }
 62     return 0;
 63 }
 64 #undef s
 65 #undef cap
 66 #undef CAP
 67 
 68 
 69 int dinic(){
 70     int ans=0,f;
 71     while (bfs()){
 72         for (int i=1;i<=CNT;i++) now[i]=first[i];
 73         while (f=dfs(S,inf)){
 74             ans+=f;
 75         }
 76     }
 77     return ans;
 78 }
 79 
 80 void make_p(){
 81     for (int i=1;i<=n;i++){
 82         for (int j=1;j<=m;j++){
 83             if (mp[i][j]){
 84                 addedge(I[i][j],O[i][j],mp[i][j]);
 85                 for (int x=i-d;x<=i+d;x++){
 86                     for (int y=j-d;y<=j+d;y++){
 87                         if (abs(i-x)+abs(j-y)>d) continue;
 88                         if (x<1 || x>n || y<1 || y>m) {addedge(O[i][j],T,inf); continue;}
 89                         if (mp[x][y] && (x!=i || y!=j)){addedge (O[i][j],I[x][y],inf); }
 90                     }
 91                 }
 92             }
 93         }
 94     }
 95 }
 96 
 97 int main(){
 98     scanf("%d%d%d",&n,&m,&d);
 99     for (int i=1;i<=n;i++){
100         char s[25];
101         scanf("%s",s+1);
102         for (int j=1;j<=m;j++){
103             mp[i][j]=s[j]-0;
104             if (mp[i][j]) I[i][j]=++CNT,O[i][j]=++CNT;
105         }
106     }
107     make_p();
108     for (int i=1;i<=n;i++){
109         char s[25];
110         scanf("%s",s+1);
111         for (int j=1;j<=m;j++){
112             if (s[j]==L){
113                 addedge(S,I[i][j],1);
114                 c++;
115             }
116         }
117     }
118     printf("%d\n",c-dinic());
119     return 0;
120 }
View Code

 

【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流