• bzoj 1066 蜥蜴


    最大流。

    建图:首先将每根柱子拆成两个点。

    每根柱子的入点向出点连一条容量为柱子高度的边。

    每根柱子的出点向可以到达的柱子的入点连一条容量为正无穷的边。

    源点向每根初始有蜥蜴的柱子的入点连一条容量为一的边。

    每根可以跳出地图的柱子的出点向汇点连一条容量为正无穷的边。

    跑一遍最大流就是最多能逃出的蜥蜴数。

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int dian=8005;
     9 const int bian=160005;
    10 const int INF=0x3f3f3f3f;
    11 int h[dian],nxt[bian],ver[bian],val[bian],ch[dian];
    12 char mapp[25][25],map[25][25];
    13 char lala[25];
    14 int n,m,d,tot,ans;
    15 int S,T;
    16 void add(int aa,int bb,int cc){
    17     tot++;ver[tot]=bb;nxt[tot]=h[aa];val[tot]=cc;h[aa]=tot;
    18     tot++;ver[tot]=aa;nxt[tot]=h[bb];val[tot]=0;h[bb]=tot;
    19 }
    20 int bh(int aa,int bb,int cc){
    21     return (aa-1)*m+bb+cc*n*m;
    22 }
    23 bool tell(){
    24     memset(ch,-1,sizeof(ch));
    25     queue<int>q;
    26     q.push(S);
    27     ch[S]=0;
    28     while(!q.empty()){
    29         int t=q.front();
    30         q.pop();
    31         for(int i=h[t];i;i=nxt[i])
    32             if(ch[ver[i]]==-1&&val[i]){
    33                 q.push(ver[i]);
    34                 ch[ver[i]]=ch[t]+1;
    35             }
    36     }
    37     return ch[T]!=-1;
    38 }
    39 int zeng(int a,int b){
    40     if(a==T)
    41         return b;
    42     int r=0;
    43     for(int i=h[a];i&&b>r;i=nxt[i])
    44         if(ch[a]+1==ch[ver[i]]&&val[i]){
    45             int t=zeng(ver[i],min(b-r,val[i]));
    46             val[i]-=t,r+=t,val[i^1]+=t;
    47         }
    48     if(!r)
    49         ch[a]=-1;
    50     return r;
    51 }
    52 int dinic(){
    53     int r=0,t;
    54     while(tell())
    55         while(t=zeng(S,INF))
    56             r+=t;
    57     return r;
    58 }
    59 int main(){
    60     tot=1;
    61     scanf("%d%d%d",&n,&m,&d);
    62     S=2*n*m+1,T=2*n*m+2;
    63     for(int i=1;i<=n;i++)
    64         scanf("%s",mapp[i]+1);
    65     for(int i=1;i<=n;i++)
    66         for(int j=1;j<=m;j++)
    67             map[i][j]=mapp[i][j]-'0';
    68     for(int i=1;i<=n;i++)
    69         for(int j=1;j<=m;j++)
    70             if(map[i][j]){
    71                 add(bh(i,j,0),bh(i,j,1),map[i][j]);
    72                 for(int k=i-d;k<=i+d;k++)
    73                     for(int l=j-d;l<=j+d;l++)
    74                         if(k>=1&&k<=n&&l>=1&&l<=m&&(k!=i||l!=j)&&abs(k-i)*abs(k-i)+abs(l-j)*abs(l-j)<=d*d&&map[k][l])
    75                             add(bh(i,j,1),bh(k,l,0),INF);
    76             }
    77     for(int i=1;i<=n;i++)
    78         for(int j=1;j<=m;j++)
    79             if(min(min(i,n+1-i),min(j,m+1-j))<=d&&map[i][j])
    80                 add(bh(i,j,1),T,INF);
    81     for(int i=1;i<=n;i++){
    82         scanf("%s",lala+1);
    83         for(int j=1;j<=m;j++)
    84             if(lala[j]=='L'){
    85                 ans++;
    86                 add(S,bh(i,j,0),1);
    87             }
    88     }
    89     printf("%d",ans-dinic());
    90     return 0;
    91 }

    注意:

    数组大小要好好算。

    读入均为字符串形式。

    距离为欧几里得距离。

  • 相关阅读:
    设置github使用的SSH key
    Github的两种协议SSH和HTTPS
    OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
    OSChina 周一乱弹 —— 为什么人类和人工智能定要一战
    APP路由还能这样玩
    APP路由还能这样玩
    APP路由还能这样玩
    APP路由还能这样玩
    掘金技术社区沸点指南(试行版)
    掘金技术社区沸点指南(试行版)
  • 原文地址:https://www.cnblogs.com/dugudashen/p/6215095.html
Copyright © 2020-2023  润新知