• 【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
    ",c-dinic());
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    J
    I题
    H
    G
    F题
    E题
    D题
    C题
    B题
    A题
  • 原文地址:https://www.cnblogs.com/karl07/p/6746389.html
Copyright © 2020-2023  润新知